Skip to content

Commit 72baa9b

Browse files
committed
Ignore external resources in CssLinkResourceTransormer
Prior to this commit, the CssLinkResourceTransformer would transform "external resources", i.e. resources not served by the web application. This commit only allows transformation for resources which path don't contain scheme such as "file://" or "http://". Only relative and absolute paths for resources served by the webapp are valid. Issue: SPR-11860
1 parent e18e449 commit 72baa9b

File tree

5 files changed

+82
-5
lines changed

5 files changed

+82
-5
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CssLinkResourceTransformer.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,10 @@ public Resource transform(HttpServletRequest request, Resource resource, Resourc
101101
for (CssLinkInfo info : sortedInfos) {
102102
writer.write(content.substring(index, info.getStart()));
103103
String link = content.substring(info.getStart(), info.getEnd());
104-
String newLink = transformerChain.getResolverChain().resolveUrlPath(link, Arrays.asList(resource));
104+
String newLink = null;
105+
if(!hasScheme(link)) {
106+
newLink = transformerChain.getResolverChain().resolveUrlPath(link, Arrays.asList(resource));
107+
}
105108
if (logger.isTraceEnabled()) {
106109
if (newLink != null && !link.equals(newLink)) {
107110
logger.trace("Link modified: " + newLink + " (original: " + link + ")");
@@ -118,6 +121,11 @@ public Resource transform(HttpServletRequest request, Resource resource, Resourc
118121
return new TransformedResource(resource, writer.toString().getBytes(DEFAULT_CHARSET));
119122
}
120123

124+
private boolean hasScheme(String link) {
125+
int schemeIndex = link.indexOf(":");
126+
return schemeIndex > 0 && !link.substring(0, schemeIndex).contains("/");
127+
}
128+
121129

122130
protected static interface CssLinkParser {
123131

spring-webmvc/src/test/java/org/springframework/web/servlet/resource/CssLinkResourceTransformerTests.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
package org.springframework.web.servlet.resource;
1818

1919
import java.util.ArrayList;
20+
import java.util.Arrays;
2021
import java.util.List;
2122

2223
import org.junit.Before;
2324
import org.junit.Test;
25+
import org.mockito.Mockito;
2426

2527
import org.springframework.core.io.ClassPathResource;
2628
import org.springframework.core.io.Resource;
@@ -77,8 +79,7 @@ public void transform() throws Exception {
7779
"@import url(bar-11e16cf79faee7ac698c805cf28248d2.css);\n\n" +
7880
"@import \"foo-e36d2e05253c6c7085a91522ce43a0b4.css\";\n" +
7981
"@import 'foo-e36d2e05253c6c7085a91522ce43a0b4.css';\n\n" +
80-
"body { background: url(\"images/image-f448cd1d5dba82b774f3202c878230b3.png\") }\n\n" +
81-
"li { list-style: url(http://www.example.com/redball.png) disc }\n";
82+
"body { background: url(\"images/image-f448cd1d5dba82b774f3202c878230b3.png\") }\n";
8283

8384
String result = new String(transformedResource.getByteArray(), "UTF-8");
8485
result = StringUtils.deleteAny(result, "\r");
@@ -92,4 +93,26 @@ public void transformNoLinks() throws Exception {
9293
assertSame(expected, actual);
9394
}
9495

96+
@Test
97+
public void transformExtLinksNotAllowed() throws Exception {
98+
ResourceResolverChain resolverChain = Mockito.mock(DefaultResourceResolverChain.class);
99+
ResourceTransformerChain transformerChain = new DefaultResourceTransformerChain(resolverChain,
100+
Arrays.asList(new CssLinkResourceTransformer()));
101+
102+
Resource externalCss = new ClassPathResource("test/external.css", getClass());
103+
Resource resource = transformerChain.transform(this.request, externalCss);
104+
TransformedResource transformedResource = (TransformedResource) resource;
105+
106+
String expected = "@import url(\"http://example.org/fonts/css\");\n" +
107+
"body { background: url(\"file:///home/spring/image.png\") }";
108+
String result = new String(transformedResource.getByteArray(), "UTF-8");
109+
result = StringUtils.deleteAny(result, "\r");
110+
assertEquals(expected, result);
111+
112+
Mockito.verify(resolverChain, Mockito.never())
113+
.resolveUrlPath("http://example.org/fonts/css", Arrays.asList(externalCss));
114+
Mockito.verify(resolverChain, Mockito.never())
115+
.resolveUrlPath("file:///home/spring/image.png", Arrays.asList(externalCss));
116+
}
117+
95118
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package org.springframework.web.servlet.resource;
2+
3+
import static org.junit.Assert.*;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
8+
import org.junit.Before;
9+
import org.junit.Test;
10+
11+
import org.springframework.core.io.ClassPathResource;
12+
import org.springframework.core.io.Resource;
13+
14+
/**
15+
* Unit tests for
16+
* {@link org.springframework.web.servlet.resource.PathResourceResolver}.
17+
*
18+
* @author Brian Clozel
19+
*/
20+
public class PathResourceResolverTests {
21+
22+
private ResourceResolverChain chain;
23+
24+
private List<Resource> locations;
25+
26+
@Before
27+
public void setup() {
28+
29+
List<ResourceResolver> resolvers = new ArrayList<>();
30+
resolvers.add(new PathResourceResolver());
31+
this.chain = new DefaultResourceResolverChain(resolvers);
32+
33+
this.locations = new ArrayList<>();
34+
this.locations.add(new ClassPathResource("test/", getClass()));
35+
}
36+
37+
@Test
38+
public void resolveResourceInternal() {
39+
String file = "bar.css";
40+
Resource expected = new ClassPathResource("test/" + file, getClass());
41+
Resource actual = this.chain.resolveResource(null, file, this.locations);
42+
43+
assertEquals(expected, actual);
44+
}
45+
46+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@import url("http://example.org/fonts/css");
2+
body { background: url("file:///home/spring/image.png") }

spring-webmvc/src/test/resources/org/springframework/web/servlet/resource/test/main.css

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,3 @@
77
@import 'foo.css';
88

99
body { background: url("images/image.png") }
10-
11-
li { list-style: url(http://www.example.com/redball.png) disc }

0 commit comments

Comments
 (0)