Giter Site home page Giter Site logo

scanny's Introduction

Scanny

Scanny is a Ruby on Rails security scanner. It parses Ruby files, looks for various suspicious patterns in them (by traversing the AST) and produces a report. Scanny aims to be simple (it does one thing well) and extensible (it is easy to define new patterns).

This is currently work in progress and it's probably not useful yet.

Installation

You need to install Rubinius first. You can then install Scanny:

$ git clone git://github.com/openSUSE/scanny.git

The scanner is not available as a gem yet (this will come soon hopefully).

Usage

To scan one or more Ruby file, use the bin/scanny command and pass the files to scan as arguments. Scanny will check the files and print a nice report:

$ cat bad.rb
`ls #{ARGV[1]}`
$ bin/scanny bad.rb
bad.rb [2 checks done | 2 nodes inspected | 1 issues]
  - [high] bad.rb:1: Backticks and %x{...} pass the executed command through shell expansion. (CWE-88, CWE-78)

Found 1 issues.

Writing New Checks

Internally, Scanny consists of multiple checks, each responsible for finding and reporting one suspicious pattern in the code. You can easily extend Scanny by writing new checks.

The checks are loaded automatically from files in the lib/scanny/checks directory. Let's look how a simple check may look like:

module Scanny
  module Checks
    # Finds all invocations of "boo" and "moo" methods.
    class BooMooCheck < Check
      def pattern
        'Send<name = :boo | :moo> | SendWithArguments<name = :boo | :moo>'
      end

      def check(node)
        issue :high, "The \"#{node.name}\" method indicates wandering cows in the code.",
              :cwe => 999
      end
    end
  end
end

Checks are subclasses of the Scanny::Checks::Check class and they implement two methods: pattern and check.

The pattern method

The pattern method returns a Machete pattern describing Rubinius AST nodes this check is interested in. See Machete documentation to learn about the pattern syntax.

Tip: When creating a check pattern it's often useful to inspect how Rubinius transforms some Ruby constructs into AST nodes. You can do this using the to_ast method:

'42'.to_ast # => #<Rubinius::AST::FixnumLiteral:0x36fc @value=42 @line=1>

The check method

The check method will be called on all AST nodes in the scanned files matched by the pattern returned by the pattern method. It will be passed the suspicious node. It can perform additional checks on it and report an issue if the node really is problematic.

Issues are reported using the issue method. As its arguments it accepts issue impact level (:info, :low, :medium or :high) and a message for the user, optionally followed by an options hash. The only currently implemented option is :cwe, which allows associating the issue with a CWE number (or multiple numbers if you pass an array).

Tests

Each check should be tested. The tests are written in RSpec and they are stored in the spec/scanny/checks directory. This is how a test for our sample check may look like:

require "spec_helper"

module Scanny::Checks
  describe BooMooCheck do
    it "reports \"boo\" correctly" do
      @runner.should check('boo').with_issue(
        issue(:high, "The \"boo\" method indicates wandering cows in the code.", 999)
      )
    end

    it "reports \"moo\" correctly" do
      @runner.should check('moo').with_issue(
        issue(:high, "The \"moo\" method indicates wandering cows in the code.", 999)
      )
    end
  end
end

Aim to create as simple test cases as possible. Also test different kinds of issues separately. See the existing tests to learn how more complex checks are tested.

Acknowledgement

The tool was written as a replacement of Thomas Biege's Ruby on Rails scanner which was used internally at SUSE. This tool needed replacement because it look for suspicious patterns using just regular expressions, which is very rough and has expressivity problems with more complex patterns.

The original AST parsing and checking code was copied and adapted from Roodi, a tool for detecting Ruby code design issues.

scanny's People

Contributors

dmajda avatar flavio avatar lte avatar thomasbiege avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.