org.zaproxy.zap.extension.replacer.ReplacerParam.java Source code

Java tutorial

Introduction

Here is the source code for org.zaproxy.zap.extension.replacer.ReplacerParam.java

Source

/*
 * Zed Attack Proxy (ZAP) and its related class files.
 *
 * ZAP is an HTTP/HTTPS proxy for assessing web application security.
 *
 * Copyright 2017 The ZAP Development Team
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.zaproxy.zap.extension.replacer;

import java.util.ArrayList;
import java.util.List;
import org.apache.commons.configuration.ConversionException;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.parosproxy.paros.common.AbstractParam;
import org.zaproxy.zap.extension.api.ZapApiIgnore;
import org.zaproxy.zap.extension.replacer.ReplacerParamRule.MatchType;

public class ReplacerParam extends AbstractParam {

    private static final Logger logger = Logger.getLogger(ReplacerParam.class);

    private static final String REPLACER_BASE_KEY = "replacer";

    private static final String ALL_RULES_KEY = REPLACER_BASE_KEY + ".full_list";

    private static final String RULE_DESCRIPTION_KEY = "description";
    private static final String RULE_ENABLED_KEY = "enabled";
    private static final String RULE_MATCH_STRING_KEY = "matchstr";
    private static final String RULE_MATCH_TYPE_KEY = "matchtype";
    private static final String RULE_REGEX_KEY = "regex";
    private static final String RULE_REPLACEMENT_KEY = "replacement";
    private static final String RULE_INITIATORS_KEY = "initiators";

    private static final String CONFIRM_REMOVE_RULE_KEY = REPLACER_BASE_KEY + ".confirmRemoveToken";

    private static ArrayList<ReplacerParamRule> defaultList = new ArrayList<ReplacerParamRule>();

    private List<ReplacerParamRule> rules = new ArrayList<>();

    private boolean confirmRemoveToken = true;

    /** Fills in the list of rules which will be added if there are none configured. */
    private void setDefaultList() {
        final String[][] defaultListArray = {
                { "Remove CSP", ReplacerParamRule.MatchType.RESP_HEADER.name(), "Content-Security-Policy", "",
                        "false", "", "false" },
                { "Remove HSTS", ReplacerParamRule.MatchType.RESP_HEADER.name(), "Strict-Transport-Security", "",
                        "false", "", "false" },
                { "Replace User-Agent with shellshock attack", ReplacerParamRule.MatchType.REQ_HEADER.name(),
                        "User-Agent", "() {:;}; /bin/cat /etc/passwd", "false", "", "false" } };

        for (String[] row : defaultListArray) {
            boolean regex = row[4].equalsIgnoreCase("true") ? true : false;
            boolean enabled = row[6].equalsIgnoreCase("true") ? true : false;
            defaultList.add(
                    new ReplacerParamRule(row[0], MatchType.valueOf(row[1]), row[2], regex, row[3], null, enabled));
        }
    }

    public ReplacerParam() {
        super();
        setDefaultList();
    }

    @Override
    protected void parse() {
        try {
            List<HierarchicalConfiguration> fields = ((HierarchicalConfiguration) getConfig())
                    .configurationsAt(ALL_RULES_KEY);
            this.rules = new ArrayList<>(fields.size());
            List<String> tempTokensNames = new ArrayList<>(fields.size());
            for (HierarchicalConfiguration sub : fields) {
                String desc = sub.getString(RULE_DESCRIPTION_KEY, "");
                if (!"".equals(desc) && !tempTokensNames.contains(desc)) {
                    boolean enabled = sub.getBoolean(RULE_ENABLED_KEY, true);
                    boolean regex = sub.getBoolean(RULE_REGEX_KEY, true);
                    String matchStr = sub.getString(RULE_MATCH_STRING_KEY, "");
                    MatchType matchType = MatchType.valueOf(
                            sub.getString(RULE_MATCH_TYPE_KEY, MatchType.RESP_BODY_STR.name()).toUpperCase());
                    String replace = sub.getString(RULE_REPLACEMENT_KEY, "");
                    String initStr = sub.getString(RULE_INITIATORS_KEY, "");
                    List<Integer> initList = null;
                    if (!StringUtils.isEmpty(initStr)) {
                        initList = new ArrayList<Integer>();
                        String[] initStrArray = initStr.replace("[", "").replace("]", "").split(",");
                        for (String str : initStrArray) {
                            try {
                                initList.add(Integer.parseInt(str.trim()));
                            } catch (NumberFormatException e) {
                                logger.error("Error while loading global repacement rule: " + e.getMessage(), e);
                            }
                        }
                    }
                    this.rules.add(
                            new ReplacerParamRule(desc, matchType, matchStr, regex, replace, initList, enabled));
                    tempTokensNames.add(desc);
                }
            }
        } catch (ConversionException e) {
            logger.error("Error while loading global repacement rules: " + e.getMessage(), e);
            this.rules = new ArrayList<>(defaultList.size());
        }

        if (this.rules.size() == 0) {
            for (ReplacerParamRule geu : defaultList) {
                this.rules.add(new ReplacerParamRule(geu));
            }
        }

        try {
            this.confirmRemoveToken = getConfig().getBoolean(CONFIRM_REMOVE_RULE_KEY, true);
        } catch (ConversionException e) {
            logger.error("Error while loading the confirm remove rule option: " + e.getMessage(), e);
        }
    }

    public List<ReplacerParamRule> getRules() {
        return rules;
    }

    public void setRules(List<ReplacerParamRule> rules) {
        this.rules = new ArrayList<>(rules);
        saveRules();
    }

    private void saveRules() {

        ((HierarchicalConfiguration) getConfig()).clearTree(ALL_RULES_KEY);

        ArrayList<String> enabledTokens = new ArrayList<>(rules.size());
        for (int i = 0, size = rules.size(); i < size; ++i) {
            String elementBaseKey = ALL_RULES_KEY + "(" + i + ").";
            ReplacerParamRule rule = rules.get(i);

            getConfig().setProperty(elementBaseKey + RULE_DESCRIPTION_KEY, rule.getDescription());
            getConfig().setProperty(elementBaseKey + RULE_ENABLED_KEY, Boolean.valueOf(rule.isEnabled()));
            getConfig().setProperty(elementBaseKey + RULE_MATCH_TYPE_KEY, rule.getMatchType().name());
            getConfig().setProperty(elementBaseKey + RULE_MATCH_STRING_KEY, rule.getMatchString());
            getConfig().setProperty(elementBaseKey + RULE_REGEX_KEY, Boolean.valueOf(rule.isMatchRegex()));
            getConfig().setProperty(elementBaseKey + RULE_REPLACEMENT_KEY, rule.getReplacement());
            List<Integer> initiators = rule.getInitiators();
            if (initiators == null || initiators.isEmpty()) {
                getConfig().setProperty(elementBaseKey + RULE_INITIATORS_KEY, "");
            } else {
                getConfig().setProperty(elementBaseKey + RULE_INITIATORS_KEY, initiators.toString());
            }

            if (rule.isEnabled()) {
                enabledTokens.add(rule.getDescription());
            }
        }

        enabledTokens.trimToSize();
    }

    public ReplacerParamRule getRule(String desc) {
        for (ReplacerParamRule rule : rules) {
            if (rule.getDescription().equals(desc)) {
                return rule;
            }
        }
        return null;
    }

    public boolean setEnabled(String desc, boolean enabled) {
        ReplacerParamRule rule = this.getRule(desc);
        if (rule != null) {
            rule.setEnabled(enabled);
            this.saveRules();
            return true;
        }
        return false;
    }

    public void addRule(ReplacerParamRule rule) {
        this.rules.add(rule);
        this.saveRules();
    }

    public boolean removeRule(String desc) {
        ReplacerParamRule rule = this.getRule(desc);
        if (rule != null) {
            this.rules.remove(rule);
            this.saveRules();
            return true;
        }
        return false;
    }

    @ZapApiIgnore
    public boolean isConfirmRemoveToken() {
        return this.confirmRemoveToken;
    }

    @ZapApiIgnore
    public void setConfirmRemoveToken(boolean confirmRemove) {
        this.confirmRemoveToken = confirmRemove;
        getConfig().setProperty(CONFIRM_REMOVE_RULE_KEY, Boolean.valueOf(confirmRemoveToken));
    }
}