The previous version of this integration made direct changes to the Checkmarx content database, but this time around that will not work, since for example CheckMarx maps it’s guidance to CWE_ID and we want to map the guidance to the Checkmarx’ Query_ID (TeamMentor has technology/application specific guidance, so we can show an SQL Injection article for Java and a different article for .NET (both have the same CWE_ID, but have different Query_ID)
Initially I was going to use PostSharp to add the TM specific code ‘on top’ of Checkmarx dlls, but since in effect this would mean the modification of CheckMarx dlls (to insert PostSharp aspects), I went for an hook on Http Pipeline instead :)
In order to allow me to develop this script, I added (a slightly modified version of ) the O2 WebREPL to a local copy of Checkmarx, so that I can execute C# directly on the server:
Since we are in the same process, we have access to all CheckMarx’s dlls, for example the main WebServices one:
the example above showed a failed login attempt, and the one below shows a successful one:
Since we have lambda methods in this REPL environment, here is a function to get a valid SessionId:
Which can then be used to fetch a particular CWE_ID description:
\
The returned style doesn’t work very well with the REPL css, but we can see that the checkmarx CWE info is there:
this is the same content that is currently retrieved from the execution of:
which looks like this.
So the objective is to have our content (i.e TeamMentor Guidance) to show there
Scripts used in this post
1) Wrap HTML Post requests
1: var cxPortal = new CxPortalWS.CxPortalWebService();
2: //var sessionId = validSessionId();
3:
4: //var cweId = 90;
5: //return cxPortal.GetQueryDescription(sessionId,cweId)
6: // .QueryDescription;
7:
8: //return validSessionId();
9:
10: System.Action requestCallback=
11: ()=>{
12: var request = System.Web.HttpContext.Current.Request;
13: var response = System.Web.HttpContext.Current.Response;
14: //response.ContentType = "text/xml";
15: if (request.Url.AbsolutePath == "/CxWebInterface/CxWebService.asmx/GetQueryDescription")
16: {
17:
18: var sessionId = request.Form["sessionId"];
19: var cweId = request.Form["cweId"].toInt();
20: //var cweId = 90;
21: var description = cxPortal.GetQueryDescription(sessionId,cweId);
22: description.QueryDescription = description.QueryDescription.replace(">CWE",">AAAAAA_CWE");
23: //response.Write(request.Form);
24: response.Write(description.toXml());
25: response.End();
26: }
27: else
28: {
29:
30: "In url: {0}".info(request.Url.AbsolutePath);
31: }
32:
33: };
34:
35:
36: "requestCallback".o2Cache<System.Action>(requestCallback);
37: //return "requestCallback".o2Cache<System.Action>();//.invoke();
38:
39:
40:
41: return "ok";
42: //return globalAsa.type().fields().select(field=>field.Name);
43: //globalAsa.field("BeginRequest_Callback", requestCallback);
44: //return globalAsa.field("BeginRequest_Callback");
45:
46: Func<string> validSessionId =
47: ()=>{
48: var credentials = new Credentials()
49: {
50: User = "admin@cx",
51: Pass = "admin"
52: };
53:
54: return cxPortal.Login(credentials,0).SessionId;
55: };
56:
57:
58: //using CxPortalWS;
59: //O2Ref:CxPortalWebService.dll
60: //O2Ref:System.Web.Services.dll
2) Getting data from InputStream (when XML form submission)
1: System.Action requestCallback=
2: ()=>{
3: var request = System.Web.HttpContext.Current.Request;
4: var response = System.Web.HttpContext.Current.Response;
5: //response.ContentType = "text/xml";
6: //if (request.Url.AbsolutePath == "/CxWebInterface/CxWebService.asmx/GetQueryDescription")
7: if (request.Url.AbsolutePath == "/Cxwebinterface/CxWebService.asmx")
8: {
9: var soapHeader = request.Headers["SOAPAction"];
10: if (soapHeader.notNull())
11: {
12: if (soapHeader == "\"http://Checkmarx.com/GetQueryDescription\"")
13: {
14: var xmlSoap = request.InputStream.bytes().ascii();
15: var elements = xmlSoap.xRoot().elementsAll();
16: //.element("{http://Checkmarx.com/}cweId");
17: //return a.xRoot().elementsAll().element("{http://Checkmarx.com/}sessionId");
18: response.Write("\n{0}\n".format(elements.size()));
19: "Handing SoapHeader: {0}".debug(soapHeader);
20: response.End();
21:
22: }
23: else
24: {
25: "Could not handle SoapHeader: [{0}]".error(soapHeader);
26: }
27: }
28: }
3) Dynamic Hook in Global.asax.cs
1: public class Global : System.Web.HttpApplication
2: {
3:
4: public Global()
5: {
6: "requestCallback".o2Cache<Action>(()=>{
7: "in Begin Request for :{0}".info(Request.Url.AbsolutePath);
8: });
9: }
10:
11:
12: protected void Application_Start (object sender, EventArgs e)
13: {
14: "[Application_Start]".info();
15: "application".o2Cache(()=>this);
16: }
17:
18: protected void Application_BeginRequest (object sender, EventArgs e)
19: {
20: var callback = "requestCallback".o2Cache<Action>();
21: callback.invoke();
22: }
23:
24: }