Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Grammar and text cleanup.

Has anyone really been far even as decided to use even go want to do
look more like?
  • Loading branch information...
commit 68371f6c73d9a382bf3ee66ab39f0c2796d50575 1 parent b514b2a
@ygjb ygjb authored
Showing with 40 additions and 47 deletions.
  1. +9 −13 README.md
  2. +20 −22 corechecks.py
  3. +9 −7 garmr.py
  4. +2 −5 reporter.py
View
22 README.md
@@ -1,24 +1,21 @@
# Garmr
-Garmr is a checking that a site meets the basic requirements from a security point of view.
-It checks what the correct HTTP calls are allowed and others are blocked. It is installable from PyPi.
+Garmr is a tool to inspect the responses from websites for basic security requirements.
-## Installation
+Garmr includes a set of core test cases implemented in corechecks that are derived from
+the Secure Coding Guidelines that can be found at [https://wiki.mozilla.org/WebAppSec/Secure_Coding_Guidelines]
-This version of garmr :
+## Installation
-* does not support pip. grab the source from git
+This version of Garmr :
+* does not support pip. Grab the source from git
* requires Requests > 0.6.2-dev, which can be installed by following the instructions here:
** http://docs.python-requests.org/en/latest/user/install/#get-the-code
-
-
## Usage
usage: garmr.py [-h] [-u TARGETS] [-m MODULES] [-f TARGET_FILES] [-p] [-d]
-Check urls for compliance with Secure Coding Guidelines
-
optional arguments:
-h, --help show this help message and exit
-u TARGETS, --url TARGETS
@@ -31,7 +28,6 @@ optional arguments:
-d, --dns Skip DNS resolution when registering a target.
## Tasks
-
-* Implement a way to provide supply parameters and specify which http verb to use
-* Implement sequences (i.e. a set of ActiveTests that once invoked, maintains a cookie jar)
-* Implement a proper reporter; currently a range of data is accumulated, but never reported.
+* Implement sequences (i.e. a series of ActiveTests that once invoked, maintains a cookie jar until the list of URLs is exhausted)
+* Implement a proper detailed reporter; currently a range of data is accumulated, but never reported.
+* Implement more checks
View
42 corechecks.py
@@ -3,8 +3,8 @@
from scanner import ActiveTest, PassiveTest, Scanner, get_url
-class HttpOnlyPresent(PassiveTest):
-
+class HttpOnlyAttributePresent(PassiveTest):
+ description = "Inspect the Set-Cookie: header and determine if the HttpOnly attribute is present."
def analyze(self, response):
cookieheader = "Set-Cookie"
has_cookie = cookieheader in response.headers
@@ -18,7 +18,7 @@ def analyze(self, response):
return result
class SecureAttributePresent(PassiveTest):
-
+ description = "Inspect the Set-Cookie: header and determine if the Secure attribute is present."
def analyze(self, response):
url = urlparse(response.url)
cookieheader = "Set-Cookie"
@@ -39,42 +39,40 @@ def analyze(self, response):
return result
-class StsHeaderPresent(PassiveTest):
-
+class StrictTransportSecurityPresent(PassiveTest):
secure_only = True
-
+ description = "Check if the Strict-Transport-Security header is present in TLS requests."
def analyze(self, response):
stsheader = "Strict-Transport-Security"
sts = stsheader in response.headers
if sts == False:
- result = self.result("Fail", "STS header not found.", None)
+ result = self.result("Fail", "Strict-Transport-Security header not found.", None)
else:
- result = self.result("Pass", "STS header present.", response.headers[stsheader])
+ result = self.result("Pass", "Strict-Transport-Security header present.", response.headers[stsheader])
return result
-class XfoPresent(PassiveTest):
-
+class XFrameOptionsPresent(PassiveTest):
description = "Check if X-Frame-Options header is present."
-
def analyze(self, response):
- xfoheader = "x-frame-options"
+ xfoheader = "X-Frame-Options"
xfo = xfoheader in response.headers
if xfo == False:
- result = self.result("Fail", "XFO header not found.", None)
+ result = self.result("Fail", "X-Frame-Options header not found.", None)
else:
- result = self.result("Pass", "XFO header present.", response.headers[xfoheader])
+ result = self.result("Pass", "X-Frame-Options header present.", response.headers[xfoheader])
return result
class RobotsTest(ActiveTest):
run_passives = True
- description = "Check for, and save the contents of robots.txt if it is present on the server."
-
+ description = "Check for the presence of a robots.txt file. If save_contents is true, the contents will be saved."
+ config = {"save_contents" : "False"}
def do_test(self, url):
u = urlparse(url)
roboturl="%s://%s/robots.txt" % (u.scheme, u.netloc)
response = requests.get(roboturl)
if response.status_code == 200:
- result = self.result("Pass", "A robots.txt file is present on the server", response.content)
+ result = self.result("Pass", "A robots.txt file is present on the server",
+ response.content if self.config["save_contents"].lower() == "true" else None)
else:
result = self.result("Fail", "No robots.txt file was found.", None)
return (result, response);
@@ -82,7 +80,7 @@ def do_test(self, url):
class StsUpgradeCheck(ActiveTest):
insecure_only = True
run_passives = False
- description = "Inspect the STS redirect process."
+ description = "Inspect the Strict-Transport-Security redirect process according to http://tools.ietf.org/html/draft-hodges-strict-transport-sec"
def do_test(self, url):
stsheader = "Strict-Transport-Security"
@@ -108,7 +106,7 @@ def do_test(self, url):
else:
message = "%s%s%s%s" % (
"The initial HTTP response included an STS header (RFC violation)." if invalid_header else "",
- "" if is_redirect else "The initial HTTP response should be a 301 redirect (RFC violation).",
+ "" if is_redirect else "The initial HTTP response should be a 301 redirect (RFC violation see ).",
"" if correct_header else "The followup to the 301 redirect must include the STS header.",
"The 301 location must use the https scheme." if bad_redirect else ""
)
@@ -119,9 +117,9 @@ def do_test(self, url):
def configure(scanner):
if isinstance(scanner, Scanner) == False:
raise Exception("Cannot configure a non-scanner object!")
- scanner.register_check(StsHeaderPresent())
- scanner.register_check(XfoPresent())
+ scanner.register_check(StrictTransportSecurityPresent())
+ scanner.register_check(XFrameOptionsPresent())
scanner.register_check(RobotsTest())
scanner.register_check(StsUpgradeCheck())
- scanner.register_check(HttpOnlyPresent())
+ scanner.register_check(HttpOnlyAttributePresent())
scanner.register_check(SecureAttributePresent())
View
16 garmr.py
@@ -6,18 +6,18 @@
import traceback
def main():
- parser = argparse.ArgumentParser(description='Check urls for compliance with Secure Coding Guidelines')
- parser.add_argument("-u", "--url", action="append", dest="targets", help="add a target to test")
- parser.add_argument("-m", "--module", action="append", default = ["corechecks"], dest="modules", help="load a test suite")
- parser.add_argument("-f", "--target-file", action="append", dest="target_files", help="File with urls to test")
+ parser = argparse.ArgumentParser("Runs a set of tests against the set of provided URLs")
+ parser.add_argument("-u", "--url", action="append", dest="targets", help="Add a target to test")
+ parser.add_argument("-f", "--target-file", action="append", dest="target_files", help="File with URLs to test")
+
+ parser.add_argument("-m", "--module", action="append", default = ["corechecks"], dest="modules", help="Load an extension module")
parser.add_argument("-p", "--force-passive", action="store_true", default=False, dest="force_passives", help ="Force passives to be run for each active test")
- parser.add_argument("-d", "--dns", action="store_false", default=True, dest="resolve_target", help ="Skip DNS resolution when registering a target.")
- parser.add_argument("-r", "--report", action="store", default="reporter.AntXmlReporter", dest="report",help="Load a reporter, format module.class, e.g. reporter.AntXmlReporter")
+ parser.add_argument("-d", "--dns", action="store_false", default=True, dest="resolve_target", help ="Skip DNS resolution when registering a target")
+ parser.add_argument("-r", "--report", action="store", default="reporter.AntXmlReporter", dest="report",help="Load a reporter e.g. -r reporter.AntXmlReporter")
parser.add_argument("-o", "--output", action="store", default="garmr-results.xml", dest="output", help="Default output is garmr-results.xml")
parser.add_argument("-c", "--check", action="append", dest="opts", help="Set a parameter for a check (check:opt=value)" )
parser.add_argument("-e", "--exclude", action="append", dest="exclusions", help="Prevent a check from being run/processed")
parser.add_argument("--save", action="store", dest="dump_path", help="Write out a configuration file based on parameters (won't run scan)")
- #todo add option to influence DNS resolution before scanning.
args = parser.parse_args()
scanner = Scanner()
@@ -44,6 +44,8 @@ def main():
Scanner.logger.error("Unable to process the target list in: %s", targets)
# Configure modules.
+ # TODO: change the module loading to scan the list of classes in a module and automagically
+ # detect any tests defined.
if args.modules != None:
for module in args.modules:
try:
View
7 reporter.py
@@ -1,10 +1,7 @@
class Reporter():
-
reporters = {}
-
- # todo - implement me!
def start_report(self):
return None
@@ -39,9 +36,9 @@ def end_report(self):
return "This reporter is unimplemented!"
class DetailReporter(Reporter):
- # TODO Implement me.
+ # TODO Implement detailed reporter
def end_report(self):
- return "This reporter should emit an XML report that includes all of the the details for each test. including captured data"
+ return "This reporter should emit an XML report that includes all of the the details for each test, including captured data"
Reporter.reporters['detail'] = DetailReporter()
Please sign in to comment.
Something went wrong with that request. Please try again.