All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.parosproxy.paros.core.scanner.VariantAbstractQuery Maven / Gradle / Ivy

Go to download

The Zed Attack Proxy (ZAP) is an easy to use integrated penetration testing tool for finding vulnerabilities in web applications. It is designed to be used by people with a wide range of security experience and as such is ideal for developers and functional testers who are new to penetration testing. ZAP provides automated scanners as well as a set of tools that allow you to find security vulnerabilities manually.

There is a newer version: 2.15.0
Show newest version
/*
 *
 * Paros and its related class files.
 *
 * Paros is an HTTP/HTTPS proxy for assessing web application security.
 * Copyright (C) 2003-2004 Chinotec Technologies Company
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the Clarified Artistic License
 * as published by the Free Software Foundation.
 *
 * 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
 * Clarified Artistic License for more details.
 *
 * You should have received a copy of the Clarified Artistic License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
// ZAP: 2012/03/15 Changed the methods (the private) setParameter and paramAppend to
// use the class StringBuilder instead of StringBuffer. Removed unnecessary
// castings in the method setParameter. Made a change in the method parse.
// ZAP: 2012/04/25 Added @Override annotation to all appropriate methods.
// ZAP: 2013/05/02 Re-arranged all modifiers into Java coding standard order
// ZAP: 2013/07/02 Changed Vector to ArrayList because obsolete and faster
// ZAP: 2013/08/21 Added a new encoding/decoding model for a correct parameter value interpretation
// ZAP: 2014/01/06 Issue 965: Support 'single page' apps and 'non standard' parameter separators
// ZAP: 2014/02/08 Used the same constants used in ScanParam Target settings
// ZAP: 2016/05/04 Changes to address issues related to ParameterParser
// ZAP: 2016/05/26 Use non-null String for names and values of parameters, scanners might not handle
// null names/values well
// ZAP: 2016/09/13 Issue 2863: Attack query string even if not originally specified
// ZAP: 2017/11/06 Use indexed names for array parameters (Issue 2496).
// ZAP: 2018/09/12 Make the addition of a query parameter optional.
// ZAP: 2019/06/01 Normalise line endings.
// ZAP: 2019/06/05 Normalise format/style.
package org.parosproxy.paros.core.scanner;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang.mutable.MutableInt;
import org.parosproxy.paros.model.Model;
import org.parosproxy.paros.network.HttpMessage;
import org.zaproxy.zap.model.ParameterParser;
import org.zaproxy.zap.model.StandardParameterParser;

public abstract class VariantAbstractQuery implements Variant {

    private List listParam;
    private List originalNames;
    private boolean addQueryParam;

    public VariantAbstractQuery() {
        listParam = Collections.emptyList();
        originalNames = Collections.emptyList();
    }

    /**
     * Build the message content setting the query string according to the Variant specific
     * implementation
     *
     * @param msg the message object we need to modify
     * @param query the query string we need to set inside the message
     */
    protected abstract void buildMessage(HttpMessage msg, String query);

    /**
     * Return escaped mutate of the value. To be overridden by subclass.
     *
     * @param msg
     * @param value
     * @return the escaped value
     */
    protected abstract String getEscapedValue(HttpMessage msg, String value);

    /**
     * Gets parameter's name in encoded/escaped form.
     *
     * 

Default implementation is to URL encode the name. * * @param msg the message that contains the parameter * @param name the name to escape * @return the escaped name * @since 2.5.0 * @see URLEncoder#encode(String, String) */ protected String getEscapedName(HttpMessage msg, String name) { return name != null ? AbstractPlugin.getURLEncode(name) : ""; } /** * Return unescaped mutate of the value. To be overridden by subclass. * * @param value * @return the unescaped value */ protected abstract String getUnescapedValue(String value); /** @deprecated (2.5.0) use {@link #setParameters(int, List)} instead. */ @Deprecated @SuppressWarnings("javadoc") protected void setParams(int type, Map params) { int i = 0; for (Entry param : params.entrySet()) { listParam.add( new NameValuePair( type, param.getKey(), getUnescapedValue(param.getValue()), i)); i++; } } /** * Sets the given {@code parameters} of the given {@code type} as the list of parameters handled * by this variant. * *

The names and values of the parameters are expected to be in decoded form. * * @param type the type of parameters * @param parameters the actual parameters to add * @throws IllegalArgumentException if {@code parameters} is {@code null}. * @since 2.5.0 * @see #getParamList() * @see NameValuePair#TYPE_QUERY_STRING * @see NameValuePair#TYPE_POST_DATA */ protected void setParameters(int type, List parameters) { if (parameters == null) { throw new IllegalArgumentException("Parameter parameters must not be null."); } int size = parameters.isEmpty() ? 1 : parameters.size(); listParam = new ArrayList<>(size); originalNames = new ArrayList<>(size); Map arraysMap = new HashMap<>(); int i = 0; for (org.zaproxy.zap.model.NameValuePair parameter : parameters) { String originalName = nonNullString(parameter.getName()); originalNames.add(originalName); String name = isParamArray(originalName) ? getArrayName(originalName, arraysMap) : originalName; listParam.add(new NameValuePair(type, name, nonNullString(parameter.getValue()), i)); i++; } if (i == 0 && addQueryParam) { String param = "query"; // No query params, lets add one just to make sure listParam.add(new NameValuePair(type, param, param, i)); originalNames.add(param); } } private static String nonNullString(String string) { if (string == null) { return ""; } return string; } private String getArrayName(String originalName, Map arraysMap) { MutableInt count = arraysMap.get(originalName); if (count == null) { count = new MutableInt(); arraysMap.put(originalName, count); } String arrayName = originalName.substring(0, originalName.length() - 2) + "[" + count + "]"; count.increment(); return arrayName; } private static boolean isParamArray(String name) { return name.endsWith("[]"); } @Override public List getParamList() { return Collections.unmodifiableList(listParam); } /** If name and value = null, not to append entire parameter. */ @Override public String setParameter( HttpMessage msg, NameValuePair originalPair, String name, String value) { return this.setParameter(msg, originalPair, name, value, false); } @Override public String setEscapedParameter( HttpMessage msg, NameValuePair originalPair, String name, String value) { return this.setParameter(msg, originalPair, name, value, true); } private String setParameter( HttpMessage msg, NameValuePair originalPair, String name, String value, boolean escaped) { // We need the correct parameter parser to use the right separators ParameterParser parser; if (originalPair.getType() == NameValuePair.TYPE_POST_DATA) { parser = Model.getSingleton() .getSession() .getFormParamParser(msg.getRequestHeader().getURI().toString()); } else if (originalPair.getType() == NameValuePair.TYPE_QUERY_STRING) { parser = Model.getSingleton() .getSession() .getUrlParamParser(msg.getRequestHeader().getURI().toString()); } else { parser = new StandardParameterParser(); } StringBuilder sb = new StringBuilder(); String encodedValue = (escaped) ? value : getEscapedValue(msg, value); NameValuePair pair; boolean isAppended; for (int i = 0; i < getParamList().size(); i++) { pair = getParamList().get(i); String origName = originalNames.get(i); if (i == originalPair.getPosition()) { isAppended = paramAppend( sb, getEscapedName(msg, pair.getName() == name ? origName : name), encodedValue, parser); } else { isAppended = paramAppend( sb, getEscapedName(msg, origName), getEscapedValue(msg, pair.getValue()), parser); } if (isAppended && i < getParamList().size() - 1) { sb.append(parser.getDefaultKeyValuePairSeparator()); } } if (sb.length() == 0) { // No original query string sb.append(encodedValue); } String query = sb.toString(); buildMessage(msg, query); return query; } /** * Set the name value pair into the StringBuilder. If both name and value is null, not to append * whole parameter. * * @param sb * @param name Null = not to append parameter. * @param value null = not to append parameter value. * @return true = parameter changed. */ private boolean paramAppend( StringBuilder sb, String name, String value, ParameterParser parser) { boolean isEdited = false; if (name != null) { sb.append(name); isEdited = true; } if (value != null) { sb.append(parser.getDefaultKeyValueSeparator()); sb.append(value); isEdited = true; } return isEdited; } public void setAddQueryParam(boolean addQueryParam) { this.addQueryParam = addQueryParam; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy