Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 134 additions & 11 deletions assembly/src/release/conf/jetty.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,31 @@

<bean id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<property name="sendServerVersion" value="false"/>
<!--
When the web console sits behind a reverse proxy or load balancer,
uncomment the customizer below so Jetty honors X-Forwarded-* (or
RFC 7239 Forwarded) headers when populating request.getRemoteAddr(),
request.getScheme(), etc. This is what gets the real client IP into
access logs and audit trails.

WARNING: ForwardedRequestCustomizer trusts these headers from any
client. Only enable it when the upstream proxy strips inbound
X-Forwarded-* headers, otherwise a remote client can spoof its
source IP and apparent scheme.

Note: this does NOT change InetAccessHandler's filtering — that
handler always evaluates the socket peer (the proxy itself) and
ignores forwarded headers. In a proxied deployment either keep the
allow list scoped to the proxy address and rely on the proxy for
client-IP filtering, or remove InetAccessHandler entirely.
-->
<!--
<property name="customizers">
<list>
<bean class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/>
</list>
</property>
-->
</bean>

<bean id="securityLoginService" class="org.eclipse.jetty.security.HashLoginService">
Expand Down Expand Up @@ -49,6 +74,10 @@
<property name="constraint" ref="adminSecurityConstraint" />
<property name="pathSpec" value="*.action" />
</bean>
<bean id="jolokiaSecurityConstraintMapping" class="org.eclipse.jetty.security.ConstraintMapping">
<property name="constraint" ref="adminSecurityConstraint" />
<property name="pathSpec" value="/api/jolokia/*" />
</bean>

<bean id="rewriteHandler" class="org.eclipse.jetty.rewrite.handler.RewriteHandler">
<property name="rules">
Expand Down Expand Up @@ -84,6 +113,24 @@
<property name="name" value="Content-Security-Policy"/>
<property name="value" value="upgrade-insecure-requests; style-src-elem 'self' 'unsafe-inline'; style-src 'self'; img-src 'self' data:; script-src-elem 'self'; default-src 'none'; object-src 'none'; frame-ancestors 'none'; base-uri 'none';" />
</bean>
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="Referrer-Policy"/>
<property name="value" value="no-referrer"/>
</bean>
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="Permissions-Policy"/>
<property name="value" value="accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()"/>
</bean>
<!-- Uncomment when serving the console over HTTPS only -->
<!--
<bean id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
<property name="pattern" value="*"/>
<property name="name" value="Strict-Transport-Security"/>
<property name="value" value="max-age=31536000; includeSubDomains"/>
</bean>
-->
</list>
</property>
</bean>
Expand Down Expand Up @@ -125,6 +172,7 @@
<property name="constraintMappings">
<list>
<ref bean="adminSecurityConstraintMapping" />
<ref bean="jolokiaSecurityConstraintMapping" />
<ref bean="securityConstraintMapping" />
</list>
</property>
Expand All @@ -140,19 +188,94 @@
<property name="port" value="8161"/>
</bean>

<bean id="handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<property name="handlers">
<list>
<ref bean="contexts" />
<ref bean="securityHandler" />
</list>
</property>
</bean>

<!--
IP-based access control for the web console.
Patterns accept: exact IP (192.168.1.1), CIDR (10.0.0.0/8),
range (10.0.0.0-10.255.255.255), or qualified with path/connector
using '|' (e.g. 192.168.1.0/24|/api).
Exclude rules take precedence over include rules.
With the default host binding of 127.0.0.1, only localhost is reachable;
if the bind address is broadened (e.g. 0.0.0.0), add explicit include
entries below for the networks that should reach the console.
-->
<bean id="inetAccessHandler" class="org.eclipse.jetty.server.handler.InetAccessHandler">
<property name="handler" ref="handlers"/>
</bean>

<!-- Allowed clients (include rules) -->
<bean id="inetAccessIncludeLoopbackV4" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="inetAccessHandler"/>
<property name="targetMethod" value="include"/>
<property name="arguments">
<list><value>127.0.0.1</value></list>
</property>
</bean>
<bean id="inetAccessIncludeLoopbackV6" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
depends-on="inetAccessIncludeLoopbackV4">
<property name="targetObject" ref="inetAccessHandler"/>
<property name="targetMethod" value="include"/>
<property name="arguments">
<list><value>::1</value></list>
</property>
</bean>
<!--
Example: allow standard private network ranges. Copy a block and
chain depends-on to enforce ordering on container startup.

<bean id="inetAccessIncludeRfc1918Class10" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
depends-on="inetAccessIncludeLoopbackV6">
<property name="targetObject" ref="inetAccessHandler"/>
<property name="targetMethod" value="include"/>
<property name="arguments">
<list><value>10.0.0.0/8</value></list>
</property>
</bean>
<bean id="inetAccessIncludeRfc1918Class172" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
depends-on="inetAccessIncludeRfc1918Class10">
<property name="targetObject" ref="inetAccessHandler"/>
<property name="targetMethod" value="include"/>
<property name="arguments">
<list><value>172.16.0.0/12</value></list>
</property>
</bean>
<bean id="inetAccessIncludeRfc1918Class192" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
depends-on="inetAccessIncludeRfc1918Class172">
<property name="targetObject" ref="inetAccessHandler"/>
<property name="targetMethod" value="include"/>
<property name="arguments">
<list><value>192.168.0.0/16</value></list>
</property>
</bean>
-->

<!--
Denied clients (exclude rules). Exclude rules take precedence over
include rules. Empty by default; add entries below to block specific
addresses or networks.

<bean id="inetAccessExcludeExample" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
depends-on="inetAccessIncludeLoopbackV6">
<property name="targetObject" ref="inetAccessHandler"/>
<property name="targetMethod" value="exclude"/>
<property name="arguments">
<list><value>1.2.3.4</value></list>
</property>
</bean>
-->

<bean id="Server" depends-on="jettyPort" class="org.eclipse.jetty.server.Server"
destroy-method="stop">

<property name="handler">
<bean id="handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<property name="handlers">
<list>
<ref bean="contexts" />
<ref bean="securityHandler" />
</list>
</property>
</bean>
</property>
<property name="handler" ref="inetAccessHandler"/>

</bean>

Expand Down Expand Up @@ -203,7 +326,7 @@
</bean>

<bean id="invokeStart" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
depends-on="broker, configureJetty, invokeConnectors">
depends-on="broker, configureJetty, invokeConnectors, inetAccessIncludeLoopbackV6">
<property name="targetObject" ref="Server" />
<property name="targetMethod" value="start" />
</bean>
Expand Down
141 changes: 140 additions & 1 deletion assembly/src/release/conf/jolokia-access.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@
-->
<restrict>

<!-- Enforce that an Origin/Referer header is present to prevent CSRF -->
<!-- Restrict HTTP methods to POST only (mitigates GET-based CSRF/SSRF vectors) -->
<http>
<method>post</method>
</http>

<!-- Enforce that an Origin/Referer header is present to prevent CSRF.
Add explicit <allow-origin> entries below if the console is served from
a different host. -->
<cors>
<strict-checking/>
</cors>
Expand Down Expand Up @@ -46,11 +53,143 @@

<!-- deny all operations or getting attributes from these mbeans -->
<deny>
<!-- ActiveMQ broker: deny destructive / privileged operations.
Safe read-only getters, browse*, and statistics queries remain allowed
via the org.apache.activemq:* entry in <allow> above. -->
<mbean>
<name>org.apache.activemq:type=Broker,brokerName=*</name>
<!-- JVM and broker lifecycle -->
<operation>terminateJVM</operation>
<operation>stop</operation>
<operation>stopGracefully</operation>
<operation>restart</operation>
<operation>gc</operation>
<!-- Topology and destination management -->
<operation>addConnector</operation>
<operation>removeConnector</operation>
<operation>addNetworkConnector</operation>
<operation>removeNetworkConnector</operation>
<operation>addQueue</operation>
<operation>removeQueue</operation>
<operation>addTopic</operation>
<operation>removeTopic</operation>
<operation>createDurableSubscriber</operation>
<operation>destroyDurableSubscriber</operation>
<!-- Runtime configuration mutation -->
<operation>reloadLog4jProperties</operation>
<operation>setMemoryLimit</operation>
<operation>setStoreLimit</operation>
<operation>setTempLimit</operation>
<operation>setJobSchedulerStoreLimit</operation>
<operation>setMaxUncommittedCount</operation>
</mbean>

<!-- Destinations: deny message data manipulation and injection.
browse / browseAsTable / counters remain allowed. -->
<mbean>
<name>org.apache.activemq:type=Broker,brokerName=*,destinationType=*,destinationName=*</name>
<operation>purge</operation>
<operation>removeMessage</operation>
<operation>removeMatchingMessages</operation>
<operation>copyMessageTo</operation>
<operation>copyMatchingMessagesTo</operation>
<operation>moveMessageTo</operation>
<operation>moveMatchingMessagesTo</operation>
<operation>retryMessage</operation>
<operation>retryMessages</operation>
<operation>removeMessageGroup</operation>
<operation>removeAllMessageGroups</operation>
<operation>sendTextMessage</operation>
<operation>sendTextMessageWithProperties</operation>
<operation>pause</operation>
<operation>resume</operation>
</mbean>

<!-- Durable subscriptions: deny destroy and selector tampering -->
<mbean>
<name>org.apache.activemq:type=Broker,brokerName=*,destinationType=*,destinationName=*,endpoint=Consumer,clientId=*,consumerId=*</name>
<operation>destroy</operation>
<operation>removeMessage</operation>
<operation>setSelector</operation>
</mbean>

<!-- JobScheduler: deny job removal -->
<mbean>
<name>org.apache.activemq:type=Broker,brokerName=*,service=JobScheduler,name=*</name>
<operation>removeJob</operation>
<operation>removeAllJobs</operation>
<operation>removeAllJobsAtScheduledTime</operation>
</mbean>

<!-- Log4JConfiguration MBean: deny runtime log level / config changes -->
<mbean>
<name>org.apache.activemq:type=Broker,brokerName=*,service=Log4JConfiguration</name>
<operation>setRootLogLevel</operation>
<operation>setLogLevel</operation>
<operation>reloadLog4jProperties</operation>
</mbean>

<!-- NetworkConnector: deny credential exposure and config mutation -->
<mbean>
<name>org.apache.activemq:type=Broker,brokerName=*,connector=networkConnectors,networkConnectorName=*</name>
<attribute>Password</attribute>
<attribute>RemotePassword</attribute>
<operation>setUserName</operation>
<operation>setPassword</operation>
<operation>setRemoteUserName</operation>
<operation>setRemotePassword</operation>
<operation>setBridgeTempDestinations</operation>
<operation>setConduitSubscriptions</operation>
<operation>setDispatchAsync</operation>
<operation>setDynamicOnly</operation>
<operation>setMessageTTL</operation>
<operation>setConsumerTTL</operation>
<operation>setPrefetchSize</operation>
<operation>setAdvisoryPrefetchSize</operation>
<operation>setDecreaseNetworkConsumerPriority</operation>
<operation>setSuppressDuplicateQueueSubscriptions</operation>
<operation>setSuppressDuplicateTopicSubscriptions</operation>
</mbean>

<!-- MLet allows remote class loading: well-known JMX/Jolokia RCE vector -->
<mbean>
<name>javax.management.loading:type=MLet</name>
<attribute>*</attribute>
<operation>*</operation>
</mbean>
<mbean>
<name>JMImplementation:*</name>
<attribute>*</attribute>
<operation>*</operation>
</mbean>
<mbean>
<name>org.apache.logging.log4j2:*</name>
<attribute>*</attribute>
<operation>*</operation>
</mbean>
<mbean>
<name>java.util.logging:*</name>
<attribute>*</attribute>
<operation>*</operation>
</mbean>
<!-- Forces GC, toggles verbose, etc. -->
<mbean>
<name>java.lang:type=Memory</name>
<attribute>*</attribute>
<operation>*</operation>
</mbean>
<mbean>
<name>java.lang:type=ClassLoading</name>
<attribute>*</attribute>
<operation>*</operation>
</mbean>
<!-- Exposes system properties and JVM input arguments -->
<mbean>
<name>java.lang:type=Runtime</name>
<attribute>SystemProperties</attribute>
<attribute>InputArguments</attribute>
<operation>*</operation>
</mbean>
<mbean>
<name>com.sun.management:type=DiagnosticCommand</name>
<attribute>*</attribute>
Expand Down
Loading