diff --git a/core/src/main/java/org/apache/struts2/action/CspReportAction.java b/core/src/main/java/org/apache/struts2/action/CspReportAction.java
new file mode 100644
index 000000000..187e7ee61
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/action/CspReportAction.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.struts2.action;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.IOException;
+
+import static org.apache.struts2.interceptor.csp.CspSettings.CSP_REPORT_TYPE;
+
+/**
+ * An abstract Action that can be extended to process the incoming CSP violation reports. Performs
+ * necessary checks to extract the JSON string of the CSP report and make sure it's a valid report.
+ * Always returns a 204 response.
+ *
+ * Override the processReport(String jsonCspReport) method to customize how the action processes
+ * the CSP report. See {@link DefaultCspReportAction} for the default implementation.
+ *
+ * Add the action to the endpoint that is the reportUri in the {@link org.apache.struts2.interceptor.csp.CspInterceptor}
+ * to collect the reports.
+ *
+ *
+ * <package name="csp-reports" namespace="/" extends="struts-default"> + * <action name="csp-reports" class="org.apache.struts2.action.DefaultCspReportAction"> + * <result type="httpheader"> + * <param name="statusCode">200</param> + * </result> + * </action> + * </package> + *+ * + * @see DefaultCspReportAction + */ +public abstract class CspReportAction extends ActionSupport implements ServletRequestAware, ServletResponseAware { + private HttpServletRequest request; + + @Override + public void withServletRequest(HttpServletRequest request) { + if (!isCspReportRequest(request)) { + return; + } + + try { + BufferedReader reader = request.getReader(); + String cspReport = reader.readLine(); + processReport(cspReport); + } catch (IOException ignored) { + } + } + + private boolean isCspReportRequest(HttpServletRequest request) { + if (!"POST".equals(request.getMethod()) || request.getContentLength() <= 0){ + return false; + } + + String contentType = request.getContentType(); + return CSP_REPORT_TYPE.equals(contentType); + } + + @Override + public void withServletResponse(HttpServletResponse response) { + response.setStatus(204); + } + + abstract void processReport(String jsonCspReport); + + public void setServletRequest(HttpServletRequest request) { + this.request = request; + } + + public HttpServletRequest getServletRequest() { + return request; + } +} diff --git a/core/src/main/java/org/apache/struts2/action/DefaultCspReportAction.java b/core/src/main/java/org/apache/struts2/action/DefaultCspReportAction.java new file mode 100644 index 000000000..3bae9f0ee --- /dev/null +++ b/core/src/main/java/org/apache/struts2/action/DefaultCspReportAction.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.struts2.action; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * The default implementation of {@link CspReportAction} that simply logs the JSON object + * that contains the details of the CSP violation. + * + * @see CspReportAction + */ +public class DefaultCspReportAction extends CspReportAction { + + protected static final Logger LOG = LogManager.getLogger(DefaultCspReportAction.class); + + @Override + void processReport(String jsonCspReport) { + LOG.error(jsonCspReport); + } +} diff --git a/core/src/main/java/org/apache/struts2/components/Link.java b/core/src/main/java/org/apache/struts2/components/Link.java new file mode 100644 index 000000000..4345c50e1 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/components/Link.java @@ -0,0 +1,175 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.struts2.components; + +import com.opensymphony.xwork2.util.ValueStack; +import org.apache.struts2.views.annotations.StrutsTag; +import org.apache.struts2.views.annotations.StrutsTagAttribute; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + *
+ * Add nonce propagation feature to implement CSP in link tags + *
+ * + *+ * The link tag allows the user to load external resources, most usually style sheets. External resources + * can inject malicious code and perform XSS and data injection attacks. The s:link tag includes a nonce + * attribute that is being randomly generated with each request and only allows links with the valid + * nonce value to be executed. + *
+ * + *Examples
+ * + *+ * + * <s:link ... /> + * + *+ * + */ +@StrutsTag(name="link", + tldTagClass="org.apache.struts2.views.jsp.ui.LinkTag", + description="Link tag automatically adds nonces to link elements - should be used in combination with Struts' CSP Interceptor.", + allowDynamicAttributes=true) +public class Link extends UIBean{ + + private static final String TEMPLATE="link"; + + protected String href; + protected String hreflang; + protected String rel; + protected String media; + protected String referrerpolicy; + protected String sizes; + protected String crossorigin; + protected String type; + protected String as; + + public Link(ValueStack stack, HttpServletRequest request, HttpServletResponse response) { + super(stack, request, response); + } + + @StrutsTagAttribute(description="HTML link href attribute") + public void setHref(String href) { + this.href = href; + } + + @StrutsTagAttribute(description="HTML link hreflang attribute") + public void setHreflang(String hreflang) { + this.hreflang = hreflang; + } + + @StrutsTagAttribute(description="HTML link rel attribute") + public void setRel(String rel) { + this.rel = rel; + } + + @StrutsTagAttribute(description="HTML link sizes attribute") + public void setSizes(String sizes) { + this.sizes = sizes; + } + + @StrutsTagAttribute(description="HTML link crossorigin attribute") + public void setCrossorigin(String crossorigin) { + this.crossorigin = crossorigin; + } + + @StrutsTagAttribute(description="HTML link type attribute") + public void setType(String type) { + this.type = type; + } + + @StrutsTagAttribute(description="HTML link as attribute") + public void setAs(String as) { + this.as = as; + } + + @StrutsTagAttribute(description="HTML link media attribute") + public void setMedia(String media) { + this.media = media; + } + + @StrutsTagAttribute(description="HTML link referrerpolicy attribute") + public void setReferrerpolicy(String referrerpolicy) { + this.referrerpolicy = referrerpolicy; + } + + @Override + protected String getDefaultTemplate() { + return TEMPLATE; + } + + @Override + protected void evaluateExtraParams() { + super.evaluateExtraParams(); + + if (href != null) { + addParameter("href", findString(href)); + } + + if (hreflang != null) { + addParameter("hreflang", findString(hreflang)); + } + + if (rel != null) { + addParameter("rel", findString(rel)); + } + + if (media != null) { + addParameter("media", findString(media)); + } + + if (referrerpolicy != null) { + addParameter("referrerpolicy", findString(referrerpolicy)); + } + + if (sizes != null) { + addParameter("sizes", findString(sizes)); + } + + if (crossorigin != null) { + addParameter("crossorigin", findString(crossorigin)); + } + + if (type != null) { + addParameter("type", findString(type)); + } + + if (as != null) { + addParameter("as", findString(as)); + } + + if (disabled != null) { + addParameter("disabled", findString(disabled)); + } + + if (title != null) { + addParameter("title", findString(title)); + } + + if (stack.getActionContext().getSession().containsKey("nonce")) { + String nonceValue = stack.getActionContext().getSession().get("nonce").toString(); + addParameter("nonce", nonceValue); + } + } +} diff --git a/core/src/main/java/org/apache/struts2/components/Script.java b/core/src/main/java/org/apache/struts2/components/Script.java new file mode 100644 index 000000000..f2a208193 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/components/Script.java @@ -0,0 +1,178 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.struts2.components; + +import com.opensymphony.xwork2.util.ValueStack; +import org.apache.struts2.views.annotations.StrutsTag; +import org.apache.struts2.views.annotations.StrutsTagAttribute; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +/** + *
+ * Add nonce propagation feature to implement CSP in script tags + *
+ * + *+ * The script tag allows the user to execute JavaScript. It also allows external resources to execute + * scripts which can be malicious. The s:script tag includes a nonce attribute that is being randomly + * generated with each request and only allows scripts with the valid nonce value to be executed. + *
+ * + *Examples
+ * + *+ * + * <s:script ... /> + * + *+ * + */ +@StrutsTag(name="script", + tldTagClass="org.apache.struts2.views.jsp.ui.ScriptTag", + description="Script tag automatically adds nonces to script blocks - should be used in combination with Struts' CSP Interceptor.", + allowDynamicAttributes=true) +public class Script extends ClosingUIBean { + + protected String async; + protected String charset; + protected String defer; + protected String src; + protected String type; + protected String referrerpolicy; + protected String nomodule; + protected String integrity; + protected String crossorigin; + + private static final String TEMPLATE = "script-close"; + private static final String OPEN_TEMPLATE = "script"; + + public Script(ValueStack stack, HttpServletRequest request, HttpServletResponse response) { + super(stack, request, response); + } + + @Override + public String getDefaultOpenTemplate() { + return OPEN_TEMPLATE; + } + + @Override + protected String getDefaultTemplate() { + return TEMPLATE; + } + + @StrutsTagAttribute(description="HTML script async attribute") + public void setAsync(String async) { + this.async = async; + } + + @StrutsTagAttribute(description="HTML script charset attribute") + public void setCharset(String charset) { + this.charset = charset; + } + + @StrutsTagAttribute(description="HTML script defer attribute") + public void setDefer(String defer) { + this.defer = defer; + } + + @StrutsTagAttribute(description="HTML script src attribute") + public void setSrc(String src) { + this.src = src; + } + + @StrutsTagAttribute(description="HTML script type attribute") + public void setType(String type) { + this.type = type; + } + + @StrutsTagAttribute(description="HTML script referrerpolicy attribute") + public void setReferrerpolicy(String referrerpolicy) { + this.referrerpolicy = referrerpolicy; + } + + @StrutsTagAttribute(description="HTML script nomodule attribute") + public void setNomodule(String nomodule) { + this.nomodule = nomodule; + } + + @StrutsTagAttribute(description="HTML script integrity attribute") + public void setIntegrity(String integrity) { + this.integrity = integrity; + } + + @StrutsTagAttribute(description="HTML script crossorigin attribute") + public void setCrossorigin(String crossorigin) { + this.crossorigin = crossorigin; + } + + @Override + public boolean usesBody() { + return true; + } + + @Override + protected void evaluateExtraParams() { + super.evaluateExtraParams(); + + if (async != null) { + addParameter("async", findString(async)); + } + + if (charset != null) { + addParameter("charset", findString(charset)); + } + + if (defer != null) { + addParameter("defer", findString(defer)); + } + + if (src != null) { + addParameter("src", findString(src)); + } + + if (type != null) { + addParameter("type", findString(type)); + } + + if (referrerpolicy != null) { + addParameter("referrerpolicy", findString(referrerpolicy)); + } + + if (nomodule != null) { + addParameter("nomodule", findString(nomodule)); + } + + if (integrity != null) { + addParameter("integrity", findString(integrity)); + } + + if (crossorigin != null) { + addParameter("crossorigin", findString(crossorigin)); + } + + if (stack.getActionContext().getSession().containsKey("nonce")) { + String nonceValue = stack.getActionContext().getSession().get("nonce").toString(); + addParameter("nonce", nonceValue); + } + } + +} diff --git a/core/src/main/java/org/apache/struts2/interceptor/csp/CspInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/csp/CspInterceptor.java new file mode 100644 index 000000000..250179636 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/interceptor/csp/CspInterceptor.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.struts2.interceptor.csp; + +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.interceptor.AbstractInterceptor; +import com.opensymphony.xwork2.interceptor.PreResultListener; +import java.net.URI; +import java.util.Optional; +import javax.servlet.http.HttpServletResponse; + +/** + * Interceptor that implements Content Security Policy on incoming requests used to protect against + * common XSS and data injection attacks. Uses {@link CspSettings} to add appropriate Content Security Policy header + * to the response. These headers determine what the browser will consider a policy violation and the browser's behavior + * when a violation occurs. A detailed explanation of CSP can be found here. + * + * @see https://csp.withgoogle.com/docs/index.html/ + * @see CspSettings + * @see DefaultCspSettings + **/ +public final class CspInterceptor extends AbstractInterceptor implements PreResultListener { + private final CspSettings settings = new DefaultCspSettings(); + + @Override + public String intercept(ActionInvocation invocation) throws Exception { + invocation.addPreResultListener(this); + return invocation.invoke(); + } + + public void beforeResult(ActionInvocation invocation, String resultCode) { + HttpServletResponse response = invocation.getInvocationContext().getServletResponse(); + settings.addCspHeaders(response); + } + + public void setReportUri(String reportUri) { + Optional
Dynamic Attributes Allowed:true |
+ |||||
| + | |||||
Name |
+ Required |
+ Default |
+ Evaluated |
+ Type |
+ Description |
+
|---|---|---|---|---|---|
| accesskey | +false | ++ | false | +String | +Set the html accesskey attribute on rendered html element | +
| as | +false | ++ | false | +String | +HTML link as attribute | +
| class | +false | ++ | false | +String | +The css class to use for element - it's an alias of cssClass attribute. | +
| crossorigin | +false | ++ | false | +String | +HTML link crossorigin attribute | +
| cssClass | +false | ++ | false | +String | +The css class to use for element | +
| cssErrorClass | +false | ++ | false | +String | +The css error class to use for element | +
| cssErrorStyle | +false | ++ | false | +String | +The css error style definitions for element to use | +
| cssStyle | +false | ++ | false | +String | +The css style definitions for element to use | +
| disabled | +false | ++ | false | +String | +Set the html disabled attribute on rendered html element | +
| errorPosition | +false | ++ | false | +String | +Define error position of form element (top|bottom) | +
| href | +false | ++ | false | +String | +HTML link href attribute | +
| hreflang | +false | ++ | false | +String | +HTML link hreflang attribute | +
| id | +false | ++ | false | +String | +HTML id attribute | +
| javascriptTooltip | +false | +false | +false | +Boolean | +Use JavaScript to generate tooltips | +
| key | +false | ++ | false | +String | +Set the key (name, value, label) for this particular component | +
| label | +false | ++ | false | +String | +Label expression used for rendering an element specific label | +
| labelSeparator | +false | +: | +false | +String | +String that will be appended to the label | +
| labelposition | +false | ++ | false | +String | +Define label position of form element (top/left) | +
| media | +false | ++ | false | +String | +HTML link media attribute | +
| name | +false | ++ | false | +String | +The name to set for element | +
| onblur | +false | ++ | false | +String | +Set the html onblur attribute on rendered html element | +
| onchange | +false | ++ | false | +String | +Set the html onchange attribute on rendered html element | +
| onclick | +false | ++ | false | +String | +Set the html onclick attribute on rendered html element | +
| ondblclick | +false | ++ | false | +String | +Set the html ondblclick attribute on rendered html element | +
| onfocus | +false | ++ | false | +String | +Set the html onfocus attribute on rendered html element | +
| onkeydown | +false | ++ | false | +String | +Set the html onkeydown attribute on rendered html element | +
| onkeypress | +false | ++ | false | +String | +Set the html onkeypress attribute on rendered html element | +
| onkeyup | +false | ++ | false | +String | +Set the html onkeyup attribute on rendered html element | +
| onmousedown | +false | ++ | false | +String | +Set the html onmousedown attribute on rendered html element | +
| onmousemove | +false | ++ | false | +String | +Set the html onmousemove attribute on rendered html element | +
| onmouseout | +false | ++ | false | +String | +Set the html onmouseout attribute on rendered html element | +
| onmouseover | +false | ++ | false | +String | +Set the html onmouseover attribute on rendered html element | +
| onmouseup | +false | ++ | false | +String | +Set the html onmouseup attribute on rendered html element | +
| onselect | +false | ++ | false | +String | +Set the html onselect attribute on rendered html element | +
| referrerpolicy | +false | ++ | false | +String | +HTML link referrerpolicy attribute | +
| rel | +false | ++ | false | +String | +HTML link rel attribute | +
| requiredLabel | +false | +false | +false | +Boolean | +If set to true, the rendered element will indicate that input is required | +
| requiredPosition | +false | ++ | false | +String | +Define required position of required form element (left|right) | +
| sizes | +false | ++ | false | +String | +HTML link sizes attribute | +
| style | +false | ++ | false | +String | +The css style definitions for element to use - it's an alias of cssStyle attribute. | +
| tabindex | +false | ++ | false | +String | +Set the html tabindex attribute on rendered html element | +
| template | +false | ++ | false | +String | +The template (other than default) to use for rendering the element | +
| templateDir | +false | ++ | false | +String | +The template directory. | +
| theme | +false | ++ | false | +String | +The theme (other than default) to use for rendering the element | +
| title | +false | ++ | false | +String | +Set the html title attribute on rendered html element | +
| tooltip | +false | ++ | false | +String | +Set the tooltip of this particular component | +
| tooltipConfig | +false | ++ | false | +String | +Deprecated. Use individual tooltip configuration attributes instead. | +
| tooltipCssClass | +false | +StrutsTTClassic | +false | +String | +CSS class applied to JavaScrip tooltips | +
| tooltipDelay | +false | +Classic | +false | +String | +Delay in milliseconds, before showing JavaScript tooltips | +
| tooltipIconPath | +false | ++ | false | +String | +Icon path used for image that will have the tooltip | +
| type | +false | ++ | false | +String | +HTML link type attribute | +
| value | +false | ++ | false | +String | +Preset the value of input element. | +
Dynamic Attributes Allowed:true |
+ |||||
| + | |||||
Name |
+ Required |
+ Default |
+ Evaluated |
+ Type |
+ Description |
+
|---|---|---|---|---|---|
| accesskey | +false | ++ | false | +String | +Set the html accesskey attribute on rendered html element | +
| async | +false | ++ | false | +String | +HTML script async attribute | +
| charset | +false | ++ | false | +String | +HTML script charset attribute | +
| class | +false | ++ | false | +String | +The css class to use for element - it's an alias of cssClass attribute. | +
| crossorigin | +false | ++ | false | +String | +HTML script crossorigin attribute | +
| cssClass | +false | ++ | false | +String | +The css class to use for element | +
| cssErrorClass | +false | ++ | false | +String | +The css error class to use for element | +
| cssErrorStyle | +false | ++ | false | +String | +The css error style definitions for element to use | +
| cssStyle | +false | ++ | false | +String | +The css style definitions for element to use | +
| defer | +false | ++ | false | +String | +HTML script defer attribute | +
| disabled | +false | ++ | false | +String | +Set the html disabled attribute on rendered html element | +
| errorPosition | +false | ++ | false | +String | +Define error position of form element (top|bottom) | +
| id | +false | ++ | false | +String | +HTML id attribute | +
| integrity | +false | ++ | false | +String | +HTML script integrity attribute | +
| javascriptTooltip | +false | +false | +false | +Boolean | +Use JavaScript to generate tooltips | +
| key | +false | ++ | false | +String | +Set the key (name, value, label) for this particular component | +
| label | +false | ++ | false | +String | +Label expression used for rendering an element specific label | +
| labelSeparator | +false | +: | +false | +String | +String that will be appended to the label | +
| labelposition | +false | ++ | false | +String | +Define label position of form element (top/left) | +
| name | +false | ++ | false | +String | +The name to set for element | +
| nomodule | +false | ++ | false | +String | +HTML script nomodule attribute | +
| onblur | +false | ++ | false | +String | +Set the html onblur attribute on rendered html element | +
| onchange | +false | ++ | false | +String | +Set the html onchange attribute on rendered html element | +
| onclick | +false | ++ | false | +String | +Set the html onclick attribute on rendered html element | +
| ondblclick | +false | ++ | false | +String | +Set the html ondblclick attribute on rendered html element | +
| onfocus | +false | ++ | false | +String | +Set the html onfocus attribute on rendered html element | +
| onkeydown | +false | ++ | false | +String | +Set the html onkeydown attribute on rendered html element | +
| onkeypress | +false | ++ | false | +String | +Set the html onkeypress attribute on rendered html element | +
| onkeyup | +false | ++ | false | +String | +Set the html onkeyup attribute on rendered html element | +
| onmousedown | +false | ++ | false | +String | +Set the html onmousedown attribute on rendered html element | +
| onmousemove | +false | ++ | false | +String | +Set the html onmousemove attribute on rendered html element | +
| onmouseout | +false | ++ | false | +String | +Set the html onmouseout attribute on rendered html element | +
| onmouseover | +false | ++ | false | +String | +Set the html onmouseover attribute on rendered html element | +
| onmouseup | +false | ++ | false | +String | +Set the html onmouseup attribute on rendered html element | +
| onselect | +false | ++ | false | +String | +Set the html onselect attribute on rendered html element | +
| openTemplate | +false | ++ | false | +String | +Set template to use for opening the rendered html. | +
| referrerpolicy | +false | ++ | false | +String | +HTML script referrerpolicy attribute | +
| requiredLabel | +false | +false | +false | +Boolean | +If set to true, the rendered element will indicate that input is required | +
| requiredPosition | +false | ++ | false | +String | +Define required position of required form element (left|right) | +
| src | +false | ++ | false | +String | +HTML script src attribute | +
| style | +false | ++ | false | +String | +The css style definitions for element to use - it's an alias of cssStyle attribute. | +
| tabindex | +false | ++ | false | +String | +Set the html tabindex attribute on rendered html element | +
| template | +false | ++ | false | +String | +The template (other than default) to use for rendering the element | +
| templateDir | +false | ++ | false | +String | +The template directory. | +
| theme | +false | ++ | false | +String | +The theme (other than default) to use for rendering the element | +
| title | +false | ++ | false | +String | +Set the html title attribute on rendered html element | +
| tooltip | +false | ++ | false | +String | +Set the tooltip of this particular component | +
| tooltipConfig | +false | ++ | false | +String | +Deprecated. Use individual tooltip configuration attributes instead. | +
| tooltipCssClass | +false | +StrutsTTClassic | +false | +String | +CSS class applied to JavaScrip tooltips | +
| tooltipDelay | +false | +Classic | +false | +String | +Delay in milliseconds, before showing JavaScript tooltips | +
| tooltipIconPath | +false | ++ | false | +String | +Icon path used for image that will have the tooltip | +
| type | +false | ++ | false | +String | +HTML script type attribute | +
| value | +false | ++ | false | +String | +Preset the value of input element. | +