/* * Zed Attack Proxy (ZAP) and its related class files. * * ZAP is an HTTP/HTTPS proxy for assessing web application security. * * Copyright 2013 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.parosproxy.paros.core.scanner; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Vector; import org.parosproxy.paros.network.HttpHeader; import org.parosproxy.paros.network.HttpMessage; /** * A {@code Variant} for Cookie headers, allowing to attack the names and values of the cookies. * * @author andy * @see Variant */ public class VariantCookie implements Variant { private List<NameValuePair> params = Collections.emptyList(); /** * @throws IllegalArgumentException if {@code message} is {@code null}. */ @Override public void setMessage(HttpMessage message) { if (message == null) { throw new IllegalArgumentException("Parameter message must not be null."); } Vector<String> cookieLines = message.getRequestHeader().getHeaders(HttpHeader.COOKIE); if (cookieLines == null) { params = Collections.emptyList(); return; } ArrayList<NameValuePair> extractedParameters = new ArrayList<>(); for (String cookieLine : cookieLines) { if (cookieLine.trim().isEmpty()) { continue; } String[] cookieArray = cookieLine.split("; ?"); for (String cookie : cookieArray) { String[] nameValuePair = cookie.split("=", 2); String name = nameValuePair[0]; String value = null; if (nameValuePair.length == 2) { value = getUnescapedValue(nameValuePair[1]); } extractedParameters.add(new NameValuePair(NameValuePair.TYPE_COOKIE, name, value, extractedParameters.size())); } } if (extractedParameters.isEmpty()) { params = Collections.emptyList(); } else { extractedParameters.trimToSize(); params = Collections.unmodifiableList(extractedParameters); } } /** * Encodes the given {@code value}. * * @param value the value that needs to be encoded, must not be {@code null}. * @return the encoded value */ private static String getEscapedValue(String value) { return AbstractPlugin.getURLEncode(value); } /** * Decodes the given {@code value}. * * @param value the value that needs to be decoded, must not be {@code null}. * @return the decoded value */ private String getUnescapedValue(String value) { return AbstractPlugin.getURLDecode(value); } /** * Gets the list of parameters (that is, cookies) extracted from the request header of the message. * * @return an unmodifiable {@code List} containing the extracted parameters, never {@code null}. */ @Override public List<NameValuePair> getParamList() { return params; } /** * * @param msg * @param originalPair * @param name * @param value * @return */ @Override public String setParameter(HttpMessage msg, NameValuePair originalPair, String name, String value) { return setParameter(msg, originalPair, name, value, false); } /** * * @param msg * @param originalPair * @param name * @param value * @return */ @Override public String setEscapedParameter(HttpMessage msg, NameValuePair originalPair, String name, String value) { return setParameter(msg, originalPair, name, value, true); } /** * * @param msg * @param originalPair * @param name * @param value * @param escaped * @return */ private String setParameter(HttpMessage msg, NameValuePair originalPair, String name, String value, boolean escaped) { String escapedValue = value == null ? null : escaped ? value : getEscapedValue(value); StringBuilder cookieString = new StringBuilder(); for (int idx = 0; idx < params.size(); idx++) { String cookieName = null; String cookieValue = null; if (idx == originalPair.getPosition()) { if (!(name == null && escapedValue == null)) { cookieName = name; if (escapedValue != null) { cookieValue = escapedValue; } } } else { NameValuePair param = params.get(idx); cookieName = param.getName(); cookieValue = param.getValue(); if (cookieValue != null) { cookieValue = getEscapedValue(cookieValue); } } if (cookieString.length() != 0 && !(cookieName == null && cookieValue == null)) { cookieString.append("; "); } if (cookieName != null) { cookieString.append(cookieName); } if (cookieValue != null) { cookieString.append('='); cookieString.append(cookieValue); } } msg.getRequestHeader().setHeader(HttpHeader.COOKIE, null); if (cookieString.length() != 0) { msg.getRequestHeader().setHeader(HttpHeader.COOKIE, cookieString.toString()); } if (escapedValue == null) { return name; } if (name == null) { return "=" + escapedValue; } return name + "=" + escapedValue; } }