mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-06-13 03:33:15 +08:00
fix(security): replace spoofable X-Forwarded-For with getRemoteAddr in rate limiter
X-Forwarded-For is client-controlled and trivially bypassable for rate limiting. Replaced with HttpServletRequest.getRemoteAddr() which uses the container-provided remote address. Added note about configuring quarkus.http.proxy.proxy-address-forwarding for trusted proxy setups.
This commit is contained in:
@@ -286,14 +286,20 @@ quarkus.vault.authentication.kubernetes.role=my-role
|
|||||||
|
|
||||||
## レート制限
|
## レート制限
|
||||||
|
|
||||||
|
**セキュリティ注意**: `X-Forwarded-For`を直接使用しないでください — クライアントが偽装できます。
|
||||||
|
サーブレットリクエストの実際のリモートアドレス、または認証済みIDを使用してください。
|
||||||
|
|
||||||
```java
|
```java
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class RateLimitFilter implements ContainerRequestFilter {
|
public class RateLimitFilter implements ContainerRequestFilter {
|
||||||
private final Map<String, RateLimiter> limiters = new ConcurrentHashMap<>();
|
private final Map<String, RateLimiter> limiters = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
HttpServletRequest servletRequest;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void filter(ContainerRequestContext requestContext) {
|
public void filter(ContainerRequestContext requestContext) {
|
||||||
String clientId = getClientIdentifier(requestContext);
|
String clientId = getClientIdentifier();
|
||||||
RateLimiter limiter = limiters.computeIfAbsent(clientId,
|
RateLimiter limiter = limiters.computeIfAbsent(clientId,
|
||||||
k -> RateLimiter.create(100.0)); // 1秒あたり100リクエスト
|
k -> RateLimiter.create(100.0)); // 1秒あたり100リクエスト
|
||||||
|
|
||||||
@@ -306,9 +312,10 @@ public class RateLimitFilter implements ContainerRequestFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getClientIdentifier(ContainerRequestContext ctx) {
|
private String getClientIdentifier() {
|
||||||
// IP、APIキー、またはユーザーIDを使用
|
// コンテナ提供のリモートアドレスを使用(X-Forwarded-Forではない)。
|
||||||
return ctx.getHeaderString("X-Forwarded-For");
|
// 信頼できるプロキシの背後にある場合はquarkus.http.proxy.proxy-address-forwarding=trueを設定。
|
||||||
|
return servletRequest.getRemoteAddr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -333,14 +333,20 @@ public class SecretService {
|
|||||||
|
|
||||||
## Rate Limiting (Hız Sınırlama)
|
## Rate Limiting (Hız Sınırlama)
|
||||||
|
|
||||||
|
**Güvenlik Notu**: `X-Forwarded-For` doğrudan kullanmayın — istemciler bunu taklit edebilir.
|
||||||
|
Servlet request'ten gerçek uzak adresi veya kimliği doğrulanmış bir kimlik (API anahtarı, JWT subject) kullanın.
|
||||||
|
|
||||||
```java
|
```java
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class RateLimitFilter implements ContainerRequestFilter {
|
public class RateLimitFilter implements ContainerRequestFilter {
|
||||||
private final Map<String, RateLimiter> limiters = new ConcurrentHashMap<>();
|
private final Map<String, RateLimiter> limiters = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
HttpServletRequest servletRequest;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void filter(ContainerRequestContext requestContext) {
|
public void filter(ContainerRequestContext requestContext) {
|
||||||
String clientId = getClientIdentifier(requestContext);
|
String clientId = getClientIdentifier();
|
||||||
RateLimiter limiter = limiters.computeIfAbsent(clientId,
|
RateLimiter limiter = limiters.computeIfAbsent(clientId,
|
||||||
k -> RateLimiter.create(100.0)); // Saniyede 100 istek
|
k -> RateLimiter.create(100.0)); // Saniyede 100 istek
|
||||||
|
|
||||||
@@ -353,9 +359,10 @@ public class RateLimitFilter implements ContainerRequestFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getClientIdentifier(ContainerRequestContext ctx) {
|
private String getClientIdentifier() {
|
||||||
// IP, API anahtarı veya kullanıcı ID'si kullanın
|
// Konteyner tarafından sağlanan uzak adresi kullanın (X-Forwarded-For değil).
|
||||||
return ctx.getHeaderString("X-Forwarded-For");
|
// Güvenilir proxy arkasındaysanız quarkus.http.proxy.proxy-address-forwarding=true ayarlayın.
|
||||||
|
return servletRequest.getRemoteAddr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -333,14 +333,21 @@ public class SecretService {
|
|||||||
|
|
||||||
## Rate Limiting
|
## Rate Limiting
|
||||||
|
|
||||||
|
**Security Note**: Never use `X-Forwarded-For` directly — clients can spoof it.
|
||||||
|
Use the actual remote address from the servlet request, or an authenticated
|
||||||
|
identity (API key, JWT subject) when available.
|
||||||
|
|
||||||
```java
|
```java
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class RateLimitFilter implements ContainerRequestFilter {
|
public class RateLimitFilter implements ContainerRequestFilter {
|
||||||
private final Map<String, RateLimiter> limiters = new ConcurrentHashMap<>();
|
private final Map<String, RateLimiter> limiters = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
HttpServletRequest servletRequest;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void filter(ContainerRequestContext requestContext) {
|
public void filter(ContainerRequestContext requestContext) {
|
||||||
String clientId = getClientIdentifier(requestContext);
|
String clientId = getClientIdentifier();
|
||||||
RateLimiter limiter = limiters.computeIfAbsent(clientId,
|
RateLimiter limiter = limiters.computeIfAbsent(clientId,
|
||||||
k -> RateLimiter.create(100.0)); // 100 requests per second
|
k -> RateLimiter.create(100.0)); // 100 requests per second
|
||||||
|
|
||||||
@@ -353,9 +360,11 @@ public class RateLimitFilter implements ContainerRequestFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getClientIdentifier(ContainerRequestContext ctx) {
|
private String getClientIdentifier() {
|
||||||
// Use IP, API key, or user ID
|
// Use the container-provided remote address (not X-Forwarded-For).
|
||||||
return ctx.getHeaderString("X-Forwarded-For");
|
// If behind a trusted proxy, configure quarkus.http.proxy.proxy-address-forwarding=true
|
||||||
|
// so getRemoteAddr() returns the real client IP.
|
||||||
|
return servletRequest.getRemoteAddr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user