Skip to content

Commit f9c1f5d

Browse files
committed
fix(通知管理): 禁止远程邮件附件地址
Closes: #770
1 parent 481e7f6 commit f9c1f5d

2 files changed

Lines changed: 50 additions & 9 deletions

File tree

jetlinks-components/notify-component/notify-email/src/main/java/org/jetlinks/community/notify/email/embedded/DefaultEmailNotifier.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import org.springframework.core.io.ByteArrayResource;
4242
import org.springframework.core.io.FileSystemResource;
4343
import org.springframework.core.io.InputStreamSource;
44-
import org.springframework.core.io.Resource;
4544
import org.springframework.core.io.buffer.DataBufferUtils;
4645
import org.springframework.http.MediaType;
4746
import org.springframework.mail.javamail.JavaMailSender;
@@ -96,8 +95,6 @@ public class DefaultEmailNotifier extends AbstractNotifier<EmailTemplate> {
9695

9796
private final FileManager fileManager;
9897

99-
private final WebClient webClient;
100-
10198
public DefaultEmailNotifier(NotifierProperties properties,
10299
TemplateManager templateManager,
103100
FileManager fileManager,
@@ -128,7 +125,6 @@ public DefaultEmailNotifier(String id,
128125
this.username = properties.getUsername();
129126
this.javaMailSender = mailSender;
130127
this.fileManager = fileManager;
131-
this.webClient = builder.build();
132128
}
133129

134130
@Nonnull
@@ -212,11 +208,8 @@ protected Mono<Void> doSend(ParsedEmailTemplate template) {
212208

213209
protected Mono<? extends InputStreamSource> convertResource(String resource) {
214210
if (resource.startsWith("http")) {
215-
return webClient
216-
.get()
217-
.uri(resource)
218-
.accept(MediaType.APPLICATION_OCTET_STREAM)
219-
.exchangeToMono(res -> res.bodyToMono(Resource.class));
211+
// 邮件模板属于发送时输入,远程地址不能触发服务端主动下载。
212+
return Mono.error(() -> new UnsupportedOperationException("不支持远程附件地址:" + resource));
220213
} else if (resource.startsWith("data:") && resource.contains(";base64,")) {
221214
String base64 = resource.substring(resource.indexOf(";base64,") + 8);
222215
return Mono.just(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2026 JetLinks https://www.jetlinks.cn
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.jetlinks.community.notify.email.embedded;
17+
18+
import org.jetlinks.community.io.file.FileManager;
19+
import org.jetlinks.community.notify.template.TemplateManager;
20+
import org.junit.jupiter.api.Test;
21+
import org.springframework.web.reactive.function.client.WebClient;
22+
import reactor.test.StepVerifier;
23+
24+
import static org.mockito.Mockito.mock;
25+
26+
class DefaultEmailNotifierTest {
27+
28+
@Test
29+
void shouldRejectRemoteAttachment() {
30+
DefaultEmailProperties properties = new DefaultEmailProperties();
31+
properties.setHost("localhost");
32+
properties.setPort(25);
33+
properties.setSender("test@example.com");
34+
35+
DefaultEmailNotifier notifier = new DefaultEmailNotifier(
36+
"test",
37+
properties,
38+
mock(TemplateManager.class),
39+
mock(FileManager.class),
40+
WebClient.builder()
41+
);
42+
43+
StepVerifier
44+
.create(notifier.convertResource("http://127.0.0.1/internal"))
45+
.expectError(UnsupportedOperationException.class)
46+
.verify();
47+
}
48+
}

0 commit comments

Comments
 (0)