Skip to content

Commit

Permalink
加固通过x-forwarded-for获取ip的场景逻辑 #5180 #5072
Browse files Browse the repository at this point in the history
加固通过x-forwarded-for获取ip的场景逻辑:
1.增加了对x-forwarded-for中存在多个ip的识别适配
2.针对万一获取到ip为null的场景进行适配
3.优化了拼接ip字符串时候判断ip是否已经存在的逻辑
均有配套单测验证。

mvn validate 验证ok
mvn clean install 无新增出错用例
  • Loading branch information
lizongbo authored and wenshao committed Nov 16, 2023
1 parent ef9d14d commit 6c9ffe6
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -251,20 +251,36 @@ public void reacord(long nanos) {
}

public void addRemoteAddress(String ip) {
if (ip == null || ip.length() < 7) {
return;
}
if (remoteAddresses == null) {
this.remoteAddresses = ip;
return;
}

if (remoteAddresses.contains(ip)) {
//判断ip是否已经存在需要考虑几种情况
//只有一个ip的情况
if (remoteAddresses.equals(ip)) {
return;
}
//是第一个ip的情况
if (remoteAddresses.startsWith(ip + ';')) {
return;
}
String addedIp = ';' + ip;
//是最后一个ip的情况
if (remoteAddresses.endsWith(addedIp)) {
return;
}
//ip已经添加在中间的场景
if (remoteAddresses.contains(';' + ip + ';')) {
return;
}

if (remoteAddresses.length() > 256) {
return;
}

remoteAddresses += ';' + ip;
remoteAddresses += addedIp;
}

public int getRunningCount() {
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/java/com/alibaba/druid/util/DruidWebUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
public class DruidWebUtils {
public static String getRemoteAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip != null && ip.contains(",")) { //截取逗号前第一个ip视为源头ip
ip = ip.substring(0, ip.indexOf(",")).trim();
}
if (ip != null && !isValidAddress(ip)) {
ip = null;
}
Expand Down Expand Up @@ -52,6 +55,9 @@ public static String getRemoteAddr(HttpServletRequest request) {

public static String getRemoteAddr(jakarta.servlet.http.HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip != null && ip.contains(",")) { //截取逗号前第一个ip视为源头ip
ip = ip.substring(0, ip.indexOf(",")).trim();
}
if (ip != null && !isValidAddress(ip)) {
ip = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
import junit.framework.TestCase;

import org.junit.Assert;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

import com.alibaba.druid.util.DruidWebUtils;

Expand All @@ -27,4 +30,46 @@ public String getContextPath() {

Assert.assertNull(DruidWebUtils.getContextPath(context));
}

/**
* @throws Exception
* @see <a href="https://github.com/alibaba/druid/issues/5180">...</a>
* see <a href="https://github.com/alibaba/druid/issues/5072">...</a>
*/
public void test_getxforwardip() throws Exception {
MockHttpServletRequest request1 = new MockHttpServletRequest() {
public String getHeader(String name) {
if ("X-Forwarded-For".equalsIgnoreCase(name)) {
return "116.228.20.212 , 10.0.25.22";
}
return super.getHeader(name);
}
};
String ip1 = DruidWebUtils.getRemoteAddr(request1);
System.out.println("X-Forwarded-For ip1===" + ip1);
assertEquals("116.228.20.212", ip1);
MockHttpServletRequest request2 = new MockHttpServletRequest() {
public String getHeader(String name) {
if ("X-Forwarded-For".equalsIgnoreCase(name)) {
return "10.0.25.22";
}
return super.getHeader(name);
}
};
String ip2 = DruidWebUtils.getRemoteAddr(request2);
System.out.println("X-Forwarded-For ip2===" + ip2);
assertEquals("10.0.25.22", ip2);

MockHttpServletRequest request3 = new MockHttpServletRequest() {
public String getHeader(String name) {
if ("X-Forwarded-For".equalsIgnoreCase(name)) {
return "x10.0.25.22";
}
return "192.168.1.3";
}
};
String ip3 = DruidWebUtils.getRemoteAddr(request3);
System.out.println("X-Forwarded-For ip3===" + ip3);
assertEquals("192.168.1.3", ip3);
}
}
33 changes: 33 additions & 0 deletions core/src/test/java/com/alibaba/druid/stat/WebSessionStatTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,37 @@ private void gc() {
System.gc();
}
}

public void test_addRemoteAddress() throws Exception {
WebSessionStat item = new WebSessionStat("1b959a6db8489c4c7ef7bf0bd743ab52");
item.addRemoteAddress("127.0.0.32");
assertEquals("127.0.0.32",item.getRemoteAddress());
item.addRemoteAddress(null);
assertEquals("127.0.0.32",item.getRemoteAddress());
item.addRemoteAddress("");
assertEquals("127.0.0.32",item.getRemoteAddress());
item.addRemoteAddress("123");
assertEquals("127.0.0.32",item.getRemoteAddress());
item.addRemoteAddress("127.0.0.32");//ip在第一个的场景
assertEquals("127.0.0.32",item.getRemoteAddress());
item.addRemoteAddress("127.0.0.23");
assertEquals("127.0.0.32;127.0.0.23",item.getRemoteAddress());
item.addRemoteAddress("127.0.0.23");//ip在最后一个的
assertEquals("127.0.0.32;127.0.0.23",item.getRemoteAddress());
item.addRemoteAddress("127.0.0.235");
assertEquals("127.0.0.32;127.0.0.23;127.0.0.235",item.getRemoteAddress());
item.addRemoteAddress("127.0.0.3");
assertEquals("127.0.0.32;127.0.0.23;127.0.0.235;127.0.0.3",item.getRemoteAddress());
item.addRemoteAddress("127.0.0.3");
assertEquals("127.0.0.32;127.0.0.23;127.0.0.235;127.0.0.3",item.getRemoteAddress());
item.addRemoteAddress("127.0.0.32");
assertEquals("127.0.0.32;127.0.0.23;127.0.0.235;127.0.0.3",item.getRemoteAddress());
item.addRemoteAddress("127.0.0.235");
assertEquals("127.0.0.32;127.0.0.23;127.0.0.235;127.0.0.3",item.getRemoteAddress());
item.addRemoteAddress("127.0.0.2");
assertEquals("127.0.0.32;127.0.0.23;127.0.0.235;127.0.0.3;127.0.0.2",item.getRemoteAddress());



}
}

0 comments on commit 6c9ffe6

Please sign in to comment.