Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 63 additions & 15 deletions DetectDynamicJS.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from array import array
from time import sleep
import difflib
import re
except ImportError:
print "Failed to load dependencies. This issue maybe caused by using an unstable Jython version."

Expand Down Expand Up @@ -71,28 +72,46 @@ def doPassiveScan(self, baseRequestResponse):
# This is, because the insertionPoint idea doesn't work well
# for this test.
scan_issues = []

if not self.isGet(baseRequestResponse.getRequest()):
baseRequestResponse = self.switchMethod(baseRequestResponse)
if (not self.isScannableRequest(baseRequestResponse) or
not self.isScript(baseRequestResponse) or
self.isProtected(baseRequestResponse)):
Comment thread
luh2 marked this conversation as resolved.
return None
newRequestResponse = self.sendUnauthenticatedRequest(baseRequestResponse)
issue = self.compareResponses(newRequestResponse, baseRequestResponse)
if not issue:
return None
# If response is script, check if script is dynamic
if self.isScript(newRequestResponse):
# sleep, in case this is a generically time stamped script
sleep(1)
secondRequestResponse = self.sendUnauthenticatedRequest(baseRequestResponse)
isDynamic = self.compareResponses(secondRequestResponse, newRequestResponse)
if isDynamic:
issue = self.reportDynamicOnly(newRequestResponse, baseRequestResponse,
secondRequestResponse)
scan_issues.append(issue)
return scan_issues
if(self.isScannableRequest(newRequestResponse)):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this could be flattened out by an early return as well.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is modified by changing the if conditions, the code is more flattened out in recent pull commit.

issue = self.compareResponses(newRequestResponse, baseRequestResponse)
if not issue:
return None
# If response is script, check if script is dynamic
if self.isScript(newRequestResponse):
# sleep, in case this is a generically time stamped script
sleep(1)
secondRequestResponse = self.sendUnauthenticatedRequest(baseRequestResponse)
isDynamic = self.compareResponses(secondRequestResponse, newRequestResponse)
if isDynamic:
issue = self.reportDynamicOnly(newRequestResponse, baseRequestResponse,
secondRequestResponse)
scan_issues.append(issue)
return scan_issues
else:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks to me like this else is not necessary. safe an indent. safe a little cats life. Makes the code more readable.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fixed as per comments.

if(self.hasScriptContent(newRequestResponse)):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small change - please check if it does not have script content - return None -> less indentation for the rest. :)

issue = self.compareResponses(newRequestResponse, baseRequestResponse)
if not issue:
return None

if self.isScript(newRequestResponse):
# sleep, in case this is a generically time stamped script
sleep(1)
secondRequestResponse = self.sendUnauthenticatedRequest(baseRequestResponse)
isDynamic = self.compareResponses(secondRequestResponse, newRequestResponse)
if isDynamic:
issue = self.reportDynamicOnly(newRequestResponse, baseRequestResponse,
secondRequestResponse)
scan_issues.append(issue)
return scan_issues
else:
return None

def sendUnauthenticatedRequest(self, requestResponse):
"""
Expand Down Expand Up @@ -341,6 +360,35 @@ def consolidateDuplicateIssues(self, existingIssue, newIssue):
else:
return 0

def has401StatusCode(self, requestResponse):
"""
Checks if the status code of the request is 401
"""
response = requestResponse.getResponse()
responseInfo = self._helpers.analyzeResponse(response)
statusCode = responseInfo.getStatusCode()
return statusCode == 401

def hasScriptContent(self,requestResponse):
"""
Checks if the response of the request contains the scipt content
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo "script"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo is fixed.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

somehow this did not make it all the way to your commit

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo is fixed in recent commit.

"""
nResponse = requestResponse.getResponse()
nResponseInfo = self._helpers.analyzeResponse(nResponse)
nBodyOffset = nResponseInfo.getBodyOffset()
nBody = nResponse.tostring()[nBodyOffset:]
first_char = nBody[0:1]
if(first_char in "[" or first_char in "{"):
return "first_char"
matchvar = re.match( r'(.*)\s*(var|let|const) ([a-zA-Z])+\s*=(.*)|(.*)\s*(window.) ([a-zA-Z])+\s*=(.*)', nBody,re.M|re.I)
matchfunction=re.match( r'(.*)\s*function\((.*)\)(.*)', nBody,re.M|re.I)

if matchvar:
return matchvar
if matchfunction:
return matchfunction
else:
return None

class ScanIssue(IScanIssue):

Expand Down