/*
*Copyright 2014 Google Inc. All rights reserved.
*
* 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 com.google.testing.security.firingrange.tests.tags;
import com.google.testing.security.firingrange.utils.Responses;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Attribute;
import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* A class only allowing a given set of tags and properties of those tags as its input payload.
*/
public class TagServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
if (request.getParameter("q") == null) {
Responses.sendError(response, "Missing q parameter", 400);
return;
}
String q = request.getParameter("q");
Document doc = Jsoup.parseBodyFragment(q);
Element body = doc.body();
Elements elements = body.getAllElements();
if (!(q.contains("body"))){
elements.remove(body);
}
if (elements.isEmpty()) {
Responses.sendError(response, "Invalid input, no tags", 400);
return;
}
String allowedTag = "";
String allowedAttribute = "";
if (request.getPathInfo() != null) {
String pathInfo = request.getPathInfo().substring(1);
if (pathInfo.contains("/")) {
allowedTag = pathInfo.split("/", 2)[0];
allowedAttribute = pathInfo.split("/")[1];
} else {
allowedTag = pathInfo;
}
}
handleRequest(elements, response, allowedTag, allowedAttribute);
}
/**
* Handles the request filtering out unallowed tags. Note that an empty allowedTag we allow
* all tags.
*/
private void handleRequest(
Elements elements, HttpServletResponse response, String allowedTag, String allowedAttr)
throws IOException {
if (allowedTag.equalsIgnoreCase("script")) {
elements.empty();
}
StringBuilder res = new StringBuilder();
for (Element element : elements) {
String tag = element.tagName();
if (!allowedTag.isEmpty() && !allowedTag.equalsIgnoreCase(tag)) {
continue;
}
if (!allowedAttr.isEmpty()) {
Attributes attributes = element.attributes();
for (Attribute attribute : attributes) {
if (!attribute.getKey().equalsIgnoreCase(allowedAttr)) {
Responses.sendError(response, "Invalid input attribute", 400);
return;
}
}
}
res.append(element.toString());
}
Responses.sendXssed(response, res.toString());
}
}