Package org.owasp.webscarab.plugin.fragments

Source Code of org.owasp.webscarab.plugin.fragments.Fragments

/***********************************************************************
*
* $CVSHeader$
*
* This file is part of WebScarab, an Open Web Application Security
* Project utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2004 Rogan Dawes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
* Getting Source
* ==============
*
* Source for this application is maintained at Sourceforge.net, a
* repository for free software projects.
*
* For details, please see http://www.sourceforge.net/projects/owasp
*
*/

/*
* Fragments.java
*
* Created on August 25, 2004, 10:45 PM
*/

package org.owasp.webscarab.plugin.fragments;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.htmlparser.nodes.RemarkNode;
import org.htmlparser.tags.FormTag;
import org.htmlparser.tags.InputTag;
import org.htmlparser.tags.ScriptTag;
import org.htmlparser.util.NodeIterator;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;
import org.owasp.webscarab.model.ConversationID;
import org.owasp.webscarab.model.HttpUrl;
import org.owasp.webscarab.model.Request;
import org.owasp.webscarab.model.Response;
import org.owasp.webscarab.model.StoreException;
import org.owasp.webscarab.parser.Parser;
import org.owasp.webscarab.plugin.Framework;
import org.owasp.webscarab.plugin.Hook;
import org.owasp.webscarab.plugin.Plugin;

/**
* This plugin looks for comments and scripts in the source of HTML pages.
* @author knoppix
*/
public class Fragments implements Plugin {
   
    private Logger _logger = Logger.getLogger(getClass().getName());
   
    private FragmentsModel _model = null;
  /**
   * Pattern that searches for window.location in right-hand side assignments.
   * Can trap potential DOM-based xss These ones search for
   * window.location,
   * window.top.location document.URL document.location document.URLUnencoded
   */
  Pattern[] jsDomXssPatterns = {
      //This one searches for
      // fobobar = window.location
      // baz = window.top.location
     
      Pattern.compile("[\\S&&[^=]]+\\s*=\\s*window\\.(?:top\\.)?location"),
      //This one searches for
      // foo= document.URL
      // bar = document.URLUnencoded
      // gazonk = document.location
      Pattern
          .compile("[\\S&&[^=]]+\\s*=\\s*document\\.(?:URL|URLUnencoded|location)"),
     
      //This one searches for string concatenation
      // such as a = "<img src='"+document.URL+"/foobar' />";
      Pattern.compile("\\+\\s*window\\.(?:top\\.)?location"),
      Pattern.compile("\\+\\s*document\\.(?:URL|URLUnencoded|location)"),
  };
 
  Pattern[] jsDomXssFalsePositivesPattern = {
    //This one removes false positives on the form
      // if(blaha != window.location)
      // if(blaha == document.URL)
      Pattern.compile(".+[!=]+=.*(?:document|window)"),
      //This one removes
      // + escape(document.location)
      //which normally is not a problem
      Pattern.compile("escape\\((?:document.|window.).+\\)"),
  };
 
    /**
     * Creates a new instance of Fragments
     * @param props contains the user's configuration properties
     */
    public Fragments(Framework framework) {
        _model = new FragmentsModel(framework.getModel());
    }
   
    public FragmentsModel getModel() {
        return _model;
    }
   
    /**
     * Sets the store that this plugin uses
     * @param session the new session
     */   
    public void setSession(String type, Object store, String session) throws StoreException {
        if (type.equals("FileSystem") && (store instanceof File)) {
            _model.setStore(new FileSystemStore((File) store, session));
        } else {
            throw new StoreException("Store type '" + type + "' is not supported in " + getClass().getName());
        }
    }
   
    /**
     * returns the name of the plugin
     * @return the name of the plugin
     */   
    public String getPluginName() {
        return "Fragments";
    }
   
    /**
     * calls the main loop of the plugin
     */
    public void run() {
        _model.setRunning(true);
    }
   
    /**
     * stops the plugin running
     * @return true if the plugin could be stopped within a (unspecified) timeout period, false otherwise
     */   
    public boolean stop() {
        _model.setRunning(false);
        return ! _model.isRunning();
    }
   
    public void analyse(ConversationID id, Request request, Response response, String origin) {
        HttpUrl url = request.getURL();
        Object parsed = Parser.parse(url, response);
        if (parsed != null && parsed instanceof NodeList) {
            NodeList nodes = (NodeList) parsed;
            try {
                NodeList comments = nodes.searchFor(RemarkNode.class);
                NodeList scripts = nodes.searchFor(ScriptTag.class);
                NodeList forms = nodes.searchFor(FormTag.class);
                NodeList inputs = nodes.searchFor(InputTag.class);
           
                for (NodeIterator ni = comments.elements(); ni.hasMoreNodes(); ) {
                    String fragment = ni.nextNode().toHtml();
                    _model.addFragment(url, id, FragmentsModel.KEY_COMMENTS, fragment);
                }
                for (NodeIterator ni = scripts.elements(); ni.hasMoreNodes(); ) {
                    String fragment = ni.nextNode().toHtml();
                    _model.addFragment(url, id, FragmentsModel.KEY_SCRIPTS, fragment);
                }
                for (NodeIterator ni = forms.elements(); ni.hasMoreNodes(); ) {
                  FormTag form = (FormTag) ni.nextNode();
                  String fragment = "action:"+form.getAttribute("action")+" method:"+form.getAttribute("method");
                  _model.addFragment(url, id, FragmentsModel.KEY_FORMS,fragment );
                }
                for (NodeIterator ni = inputs.elements(); ni.hasMoreNodes(); ) {
                  InputTag tag = (InputTag) ni.nextNode();
                  String type = tag.getAttribute("type");
                  if( "hidden".equals(type))
                  {
                    String fragment = tag.toHtml();
                    _model.addFragment(url, id, FragmentsModel.KEY_HIDDENFIELD, fragment);
                  }
                  if("file".equals(type))
                  {
                    String fragment = tag.toHtml();
                    _model.addFragment(url, id, FragmentsModel.KEY_FILEUPLOAD, fragment);
                  }
                }
            } catch (ParserException pe) {
                _logger.warning("Looking for fragments, got '" + pe + "'");
            }
        }
        //Now, look for "dangerous" javascript
        try {
      String content = new String(response.getContent(),"UTF-8");
      for (int i = 0; i < jsDomXssPatterns.length; i++) {
        Matcher m = jsDomXssPatterns[i].matcher(content);
        while(m.find())
        {
          String fragment = m.group();
          boolean falsePositive = false;
          //Test false positives
          for (int j = 0; j < jsDomXssFalsePositivesPattern.length; j++) {
            Matcher fp = jsDomXssFalsePositivesPattern[j]
                .matcher(fragment);
            if (fp.find()) {
              falsePositive = true;
              _logger
                  .info("Ignoring XSS-DOM fragment '"
                      + fragment
                      + "' - false positive according to pattern :"
                      + jsDomXssFalsePositivesPattern[j]
                          .pattern());
              break;
            }
          }
          if (!falsePositive)
          {
            _model.addFragment(url, id, FragmentsModel.KEY_DOMXSS,
                fragment);
          }
         
        }
      }
    } catch (UnsupportedEncodingException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
       
       
    }
    public void flush() throws StoreException {
        _model.flush();
    }
   
    public boolean isBusy() {
        return _model.isBusy();
    }
   
    public String getStatus() {
        return _model.getStatus();
    }
   
    public boolean isModified() {
        return _model.isModified();
    }
   
    public boolean isRunning() {
        return _model.isRunning();
    }
   
    public Object getScriptableObject() {
        return null;
    }
   
    public Hook[] getScriptingHooks() {
        return new Hook[0];
    }
   
}
TOP

Related Classes of org.owasp.webscarab.plugin.fragments.Fragments

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.