Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
0ab81e4f
Commit
0ab81e4f
authored
Jul 24, 2017
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Prevent loader classes from being served by executable war
Closes gh-5550
parent
5516e862
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
262 additions
and
18 deletions
+262
-18
EmbeddedServletContainerWarPackagingIntegrationTests.java
...EmbeddedServletContainerWarPackagingIntegrationTests.java
+11
-0
JettyServletWebServerFactory.java
...boot/web/embedded/jetty/JettyServletWebServerFactory.java
+97
-3
TomcatServletWebServerFactory.java
...ot/web/embedded/tomcat/TomcatServletWebServerFactory.java
+108
-2
UndertowServletWebServerFactory.java
...eb/embedded/undertow/UndertowServletWebServerFactory.java
+46
-13
No files found.
spring-boot-integration-tests/spring-boot-integration-tests-embedded-servlet-container/src/test/java/org/springframework/boot/context/embedded/EmbeddedServletContainerWarPackagingIntegrationTests.java
View file @
0ab81e4f
...
@@ -86,4 +86,15 @@ public class EmbeddedServletContainerWarPackagingIntegrationTests
...
@@ -86,4 +86,15 @@ public class EmbeddedServletContainerWarPackagingIntegrationTests
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
OK
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
OK
);
}
}
@Test
public
void
loaderClassesAreNotAvailableViaHttp
()
throws
Exception
{
ResponseEntity
<
String
>
entity
=
this
.
rest
.
getForEntity
(
"/org/springframework/boot/loader/Launcher.class"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
NOT_FOUND
);
entity
=
this
.
rest
.
getForEntity
(
"/org/springframework/../springframework/boot/loader/Launcher.class"
,
String
.
class
);
assertThat
(
entity
.
getStatusCode
()).
isEqualTo
(
HttpStatus
.
NOT_FOUND
);
}
}
}
spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java
View file @
0ab81e4f
...
@@ -18,8 +18,11 @@ package org.springframework.boot.web.embedded.jetty;
...
@@ -18,8 +18,11 @@ package org.springframework.boot.web.embedded.jetty;
import
java.io.File
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.net.InetSocketAddress
;
import
java.net.InetSocketAddress
;
import
java.net.MalformedURLException
;
import
java.net.URL
;
import
java.net.URL
;
import
java.nio.channels.ReadableByteChannel
;
import
java.nio.charset.Charset
;
import
java.nio.charset.Charset
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
...
@@ -389,12 +392,14 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
...
@@ -389,12 +392,14 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
private
void
configureDocumentRoot
(
WebAppContext
handler
)
{
private
void
configureDocumentRoot
(
WebAppContext
handler
)
{
File
root
=
getValidDocumentRoot
();
File
root
=
getValidDocumentRoot
();
root
=
(
root
!=
null
?
root
:
createTempDir
(
"jetty-docbase"
));
File
docBase
=
(
root
!=
null
?
root
:
createTempDir
(
"jetty-docbase"
));
try
{
try
{
List
<
Resource
>
resources
=
new
ArrayList
<>();
List
<
Resource
>
resources
=
new
ArrayList
<>();
Resource
rootResource
=
docBase
.
isDirectory
()
?
Resource
.
newResource
(
docBase
.
getCanonicalFile
())
:
JarResource
.
newJarResource
(
Resource
.
newResource
(
docBase
));
resources
.
add
(
resources
.
add
(
root
.
isDirectory
()
?
Resource
.
newResource
(
root
.
getCanonicalFile
())
root
==
null
?
rootResource
:
new
LoaderHidingResource
(
rootResource
));
:
JarResource
.
newJarResource
(
Resource
.
newResource
(
root
)));
for
(
URL
resourceJarUrl
:
this
.
getUrlsOfJarsWithMetaInfResources
())
{
for
(
URL
resourceJarUrl
:
this
.
getUrlsOfJarsWithMetaInfResources
())
{
Resource
resource
=
createResource
(
resourceJarUrl
);
Resource
resource
=
createResource
(
resourceJarUrl
);
// Jetty 9.2 and earlier do not support nested jars. See
// Jetty 9.2 and earlier do not support nested jars. See
...
@@ -719,4 +724,93 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
...
@@ -719,4 +724,93 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
}
}
private
static
final
class
LoaderHidingResource
extends
Resource
{
private
final
Resource
delegate
;
private
LoaderHidingResource
(
Resource
delegate
)
{
this
.
delegate
=
delegate
;
}
@Override
public
Resource
addPath
(
String
path
)
throws
IOException
,
MalformedURLException
{
if
(
path
.
startsWith
(
"/org/springframework/boot"
))
{
return
null
;
}
return
this
.
delegate
.
addPath
(
path
);
}
@Override
public
boolean
isContainedIn
(
Resource
resource
)
throws
MalformedURLException
{
return
this
.
delegate
.
isContainedIn
(
resource
);
}
@Override
public
void
close
()
{
close
();
}
@Override
public
boolean
exists
()
{
return
this
.
delegate
.
exists
();
}
@Override
public
boolean
isDirectory
()
{
return
this
.
delegate
.
isDirectory
();
}
@Override
public
long
lastModified
()
{
return
this
.
delegate
.
lastModified
();
}
@Override
public
long
length
()
{
return
this
.
delegate
.
length
();
}
@Override
@Deprecated
public
URL
getURL
()
{
return
this
.
delegate
.
getURL
();
}
@Override
public
File
getFile
()
throws
IOException
{
return
this
.
delegate
.
getFile
();
}
@Override
public
String
getName
()
{
return
this
.
delegate
.
getName
();
}
@Override
public
InputStream
getInputStream
()
throws
IOException
{
return
this
.
delegate
.
getInputStream
();
}
@Override
public
ReadableByteChannel
getReadableByteChannel
()
throws
IOException
{
return
this
.
delegate
.
getReadableByteChannel
();
}
@Override
public
boolean
delete
()
throws
SecurityException
{
return
this
.
delegate
.
delete
();
}
@Override
public
boolean
renameTo
(
Resource
dest
)
throws
SecurityException
{
return
this
.
delegate
.
renameTo
(
dest
);
}
@Override
public
String
[]
list
()
{
return
this
.
delegate
.
list
();
}
}
}
}
spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java
View file @
0ab81e4f
...
@@ -18,6 +18,8 @@ package org.springframework.boot.web.embedded.tomcat;
...
@@ -18,6 +18,8 @@ package org.springframework.boot.web.embedded.tomcat;
import
java.io.File
;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.io.FileNotFoundException
;
import
java.io.InputStream
;
import
java.lang.reflect.Method
;
import
java.net.URL
;
import
java.net.URL
;
import
java.nio.charset.Charset
;
import
java.nio.charset.Charset
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
...
@@ -39,16 +41,23 @@ import org.apache.catalina.Engine;
...
@@ -39,16 +41,23 @@ import org.apache.catalina.Engine;
import
org.apache.catalina.Host
;
import
org.apache.catalina.Host
;
import
org.apache.catalina.Lifecycle
;
import
org.apache.catalina.Lifecycle
;
import
org.apache.catalina.LifecycleEvent
;
import
org.apache.catalina.LifecycleEvent
;
import
org.apache.catalina.LifecycleException
;
import
org.apache.catalina.LifecycleListener
;
import
org.apache.catalina.LifecycleListener
;
import
org.apache.catalina.Manager
;
import
org.apache.catalina.Manager
;
import
org.apache.catalina.Valve
;
import
org.apache.catalina.Valve
;
import
org.apache.catalina.WebResource
;
import
org.apache.catalina.WebResourceRoot.ResourceSetType
;
import
org.apache.catalina.WebResourceRoot.ResourceSetType
;
import
org.apache.catalina.WebResourceSet
;
import
org.apache.catalina.Wrapper
;
import
org.apache.catalina.Wrapper
;
import
org.apache.catalina.connector.Connector
;
import
org.apache.catalina.connector.Connector
;
import
org.apache.catalina.loader.WebappLoader
;
import
org.apache.catalina.loader.WebappLoader
;
import
org.apache.catalina.session.StandardManager
;
import
org.apache.catalina.session.StandardManager
;
import
org.apache.catalina.startup.Tomcat
;
import
org.apache.catalina.startup.Tomcat
;
import
org.apache.catalina.startup.Tomcat.FixContextListener
;
import
org.apache.catalina.startup.Tomcat.FixContextListener
;
import
org.apache.catalina.util.LifecycleBase
;
import
org.apache.catalina.webresources.AbstractResourceSet
;
import
org.apache.catalina.webresources.EmptyResource
;
import
org.apache.catalina.webresources.StandardRoot
;
import
org.apache.catalina.webresources.TomcatURLStreamHandlerFactory
;
import
org.apache.catalina.webresources.TomcatURLStreamHandlerFactory
;
import
org.apache.coyote.AbstractProtocol
;
import
org.apache.coyote.AbstractProtocol
;
import
org.apache.coyote.ProtocolHandler
;
import
org.apache.coyote.ProtocolHandler
;
...
@@ -71,6 +80,7 @@ import org.springframework.context.ResourceLoaderAware;
...
@@ -71,6 +80,7 @@ import org.springframework.context.ResourceLoaderAware;
import
org.springframework.core.io.ResourceLoader
;
import
org.springframework.core.io.ResourceLoader
;
import
org.springframework.util.Assert
;
import
org.springframework.util.Assert
;
import
org.springframework.util.ClassUtils
;
import
org.springframework.util.ClassUtils
;
import
org.springframework.util.ReflectionUtils
;
import
org.springframework.util.ResourceUtils
;
import
org.springframework.util.ResourceUtils
;
import
org.springframework.util.StringUtils
;
import
org.springframework.util.StringUtils
;
...
@@ -183,12 +193,16 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto
...
@@ -183,12 +193,16 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto
}
}
protected
void
prepareContext
(
Host
host
,
ServletContextInitializer
[]
initializers
)
{
protected
void
prepareContext
(
Host
host
,
ServletContextInitializer
[]
initializers
)
{
File
docBase
=
getValidDocumentRoot
();
File
documentRoot
=
getValidDocumentRoot
();
docBase
=
(
docBase
!=
null
?
docBase
:
createTempDir
(
"tomcat-docbase"
));
final
TomcatEmbeddedContext
context
=
new
TomcatEmbeddedContext
();
final
TomcatEmbeddedContext
context
=
new
TomcatEmbeddedContext
();
if
(
documentRoot
!=
null
)
{
context
.
setResources
(
new
LoaderHidingResourceRoot
(
context
));
}
context
.
setName
(
getContextPath
());
context
.
setName
(
getContextPath
());
context
.
setDisplayName
(
getDisplayName
());
context
.
setDisplayName
(
getDisplayName
());
context
.
setPath
(
getContextPath
());
context
.
setPath
(
getContextPath
());
File
docBase
=
(
documentRoot
!=
null
?
documentRoot
:
createTempDir
(
"tomcat-docbase"
));
context
.
setDocBase
(
docBase
.
getAbsolutePath
());
context
.
setDocBase
(
docBase
.
getAbsolutePath
());
context
.
addLifecycleListener
(
new
FixContextListener
());
context
.
addLifecycleListener
(
new
FixContextListener
());
context
.
setParentClassLoader
(
context
.
setParentClassLoader
(
...
@@ -839,4 +853,96 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto
...
@@ -839,4 +853,96 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto
}
}
private
static
final
class
LoaderHidingResourceRoot
extends
StandardRoot
{
private
LoaderHidingResourceRoot
(
TomcatEmbeddedContext
context
)
{
super
(
context
);
}
@Override
protected
WebResourceSet
createMainResourceSet
()
{
return
new
LoaderHidingWebResourceSet
(
super
.
createMainResourceSet
());
}
}
private
static
final
class
LoaderHidingWebResourceSet
extends
AbstractResourceSet
{
private
final
WebResourceSet
delegate
;
private
final
Method
initInternal
;
private
LoaderHidingWebResourceSet
(
WebResourceSet
delegate
)
{
this
.
delegate
=
delegate
;
try
{
this
.
initInternal
=
LifecycleBase
.
class
.
getDeclaredMethod
(
"initInternal"
);
this
.
initInternal
.
setAccessible
(
true
);
}
catch
(
Exception
ex
)
{
throw
new
IllegalStateException
(
ex
);
}
}
@Override
public
WebResource
getResource
(
String
path
)
{
if
(
path
.
startsWith
(
"/org/springframework/boot"
))
{
return
new
EmptyResource
(
getRoot
(),
path
);
}
return
this
.
delegate
.
getResource
(
path
);
}
@Override
public
String
[]
list
(
String
path
)
{
return
this
.
delegate
.
list
(
path
);
}
@Override
public
Set
<
String
>
listWebAppPaths
(
String
path
)
{
return
this
.
delegate
.
listWebAppPaths
(
path
);
}
@Override
public
boolean
mkdir
(
String
path
)
{
return
this
.
delegate
.
mkdir
(
path
);
}
@Override
public
boolean
write
(
String
path
,
InputStream
is
,
boolean
overwrite
)
{
return
this
.
delegate
.
write
(
path
,
is
,
overwrite
);
}
@Override
public
URL
getBaseUrl
()
{
return
this
.
delegate
.
getBaseUrl
();
}
@Override
public
void
setReadOnly
(
boolean
readOnly
)
{
this
.
delegate
.
setReadOnly
(
readOnly
);
}
@Override
public
boolean
isReadOnly
()
{
return
this
.
delegate
.
isReadOnly
();
}
@Override
public
void
gc
()
{
this
.
delegate
.
gc
();
}
@Override
protected
void
initInternal
()
throws
LifecycleException
{
if
(
this
.
delegate
instanceof
LifecycleBase
)
{
try
{
ReflectionUtils
.
invokeMethod
(
this
.
initInternal
,
this
.
delegate
);
}
catch
(
Exception
ex
)
{
throw
new
LifecycleException
(
ex
);
}
}
}
}
}
}
spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactory.java
View file @
0ab81e4f
...
@@ -486,13 +486,15 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
...
@@ -486,13 +486,15 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
}
}
private
ResourceManager
getDocumentRootResourceManager
()
{
private
ResourceManager
getDocumentRootResourceManager
()
{
File
root
=
getCanonicalDocumentRoot
();
File
root
=
getValidDocumentRoot
();
File
docBase
=
getCanonicalDocumentRoot
(
root
);
List
<
URL
>
metaInfResourceUrls
=
getUrlsOfJarsWithMetaInfResources
();
List
<
URL
>
metaInfResourceUrls
=
getUrlsOfJarsWithMetaInfResources
();
List
<
URL
>
resourceJarUrls
=
new
ArrayList
<
URL
>();
List
<
URL
>
resourceJarUrls
=
new
ArrayList
<
URL
>();
List
<
ResourceManager
>
resourceManagers
=
new
ArrayList
<
ResourceManager
>();
List
<
ResourceManager
>
resourceManagers
=
new
ArrayList
<
ResourceManager
>();
ResourceManager
rootResourceManager
=
root
.
isDirectory
()
ResourceManager
rootResourceManager
=
docBase
.
isDirectory
()
?
new
FileResourceManager
(
root
,
0
)
:
new
JarResourceManager
(
root
);
?
new
FileResourceManager
(
docBase
,
0
)
:
new
JarResourceManager
(
docBase
);
resourceManagers
.
add
(
rootResourceManager
);
resourceManagers
.
add
(
root
==
null
?
rootResourceManager
:
new
LoaderHidingResourceManager
(
rootResourceManager
));
for
(
URL
url
:
metaInfResourceUrls
)
{
for
(
URL
url
:
metaInfResourceUrls
)
{
if
(
"file"
.
equals
(
url
.
getProtocol
()))
{
if
(
"file"
.
equals
(
url
.
getProtocol
()))
{
File
file
=
new
File
(
url
.
getFile
());
File
file
=
new
File
(
url
.
getFile
());
...
@@ -518,16 +520,9 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
...
@@ -518,16 +520,9 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
resourceManagers
.
toArray
(
new
ResourceManager
[
resourceManagers
.
size
()]));
resourceManagers
.
toArray
(
new
ResourceManager
[
resourceManagers
.
size
()]));
}
}
/**
private
File
getCanonicalDocumentRoot
(
File
docBase
)
{
* Return the document root in canonical form. Undertow uses File#getCanonicalFile()
* to determine whether a resource has been requested using the proper case but on
* Windows {@code java.io.tmpdir} may be set as a tilde-compressed pathname.
* @return the canonical document root
*/
private
File
getCanonicalDocumentRoot
()
{
try
{
try
{
File
root
=
getValidDocumentRoot
();
File
root
=
docBase
!=
null
?
docBase
:
createTempDir
(
"undertow-docbase"
);
root
=
(
root
!=
null
?
root
:
createTempDir
(
"undertow-docbase"
));
return
root
.
getCanonicalFile
();
return
root
.
getCanonicalFile
();
}
}
catch
(
IOException
e
)
{
catch
(
IOException
e
)
{
...
@@ -803,4 +798,42 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
...
@@ -803,4 +798,42 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
}
}
private
static
final
class
LoaderHidingResourceManager
implements
ResourceManager
{
private
final
ResourceManager
delegate
;
private
LoaderHidingResourceManager
(
ResourceManager
delegate
)
{
this
.
delegate
=
delegate
;
}
@Override
public
Resource
getResource
(
String
path
)
throws
IOException
{
if
(
path
.
startsWith
(
"/org/springframework/boot"
))
{
return
null
;
}
return
this
.
delegate
.
getResource
(
path
);
}
@Override
public
boolean
isResourceChangeListenerSupported
()
{
return
this
.
delegate
.
isResourceChangeListenerSupported
();
}
@Override
public
void
registerResourceChangeListener
(
ResourceChangeListener
listener
)
{
this
.
delegate
.
registerResourceChangeListener
(
listener
);
}
@Override
public
void
removeResourceChangeListener
(
ResourceChangeListener
listener
)
{
this
.
delegate
.
removeResourceChangeListener
(
listener
);
}
@Override
public
void
close
()
throws
IOException
{
this
.
delegate
.
close
();
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment