Yaygın olarak “Yol Geçişi” olarak adlandırılan Ortak Zayıflık Sayımı CWE-22, bir uygulamanın, kullanıcıların kullanıcı tarafından sağlanan giriş yoluyla erişebileceği yolları düzgün şekilde kısıtlamadığı bir güvenlik açığıdır. Bu, saldırganların amaçlanan dizin dışındaki dizinlere ve dosyalara erişmesine olanak tanıyarak yetkisiz erişime ve sistemin tehlikeye girmesine neden olabilir. Bu güvenlik açığı, dosya işleme ve web kaynaklarının her yerde kullanılması nedeniyle Java uygulamalarında özellikle önemlidir. Bu yazı CWE-22'nin doğasını, etkisini, yararlanma yöntemlerini ve en önemlisi Java uygulamalarındaki bu tür güvenlik açıklarını azaltmaya yönelik stratejileri kapsar.
Duyuru
Sven, 1996'dan bu yana ve 15 yılı aşkın bir süredir dünya çapında otomotiv, havacılık, sigorta, bankacılık, Birleşmiş Milletler ve Dünya Bankası gibi endüstrilerde endüstriyel projelerde Java programlıyor. 10 yıldan fazla bir süredir Amerika'dan Yeni Zelanda'ya kadar konferanslarda ve topluluk etkinliklerinde konuşmacı olarak yer alıyor, JFrog ve Vaadin için geliştirici savunucusu olarak çalışıyor ve düzenli olarak BT dergileri ve teknoloji portalları için makaleler yazıyor. Ana konusu olan Core Java'nın yanı sıra TDD ve güvenli kodlama uygulamalarını da kapsar.
Kısaca CWE-22
CWE-22, “Yol adının kısıtlı bir dizine uygunsuz şekilde kısıtlanması (Yol Geçişi)” olarak sınıflandırılmıştır. Güvenlik açığı, bir uygulamanın uygun doğrulama veya temizleme olmadan bir yol oluşturmak için kullanıcı girişini kullanması ve birinin amaçlanan dizinin dışına çıkan yolları belirlemesine izin vermesi durumunda ortaya çıkar. Dizin yapısında bir seviye yukarı çıkmak için ../ gibi diziler kullanılabilir.
Örneğin, kullanıcı girdisine dayalı olarak bir dosyayı okuyan tipik bir Java kod parçacığı şuna benzer:
String fileName = request.getParameter("file");
File file = new File("/var/www/uploads/" + fileName);
FileInputStream fis = new FileInputStream(file);
Bu parametre fileName Düzgün bir şekilde doğrulanmazsa, bir saldırgan, bir yol geçiş sırası (`. ./.. /etc/passwd) kullanarak /var/www/uploads/ dizini dışındaki dosyalara erişmek için onu değiştirebilir, örneğin: B. /etc/passwd `).
CWE-22'nin Etkisi
CWE-22'nin etkisi ciddi olabilir ve hassas dosyalara yetkisiz erişimden sistemin tamamen tehlikeye atılmasına kadar değişebilir. Olası etkiler şunları içerir:
Saldırgan, Yol Geçişi güvenlik açığından yararlanmak için dosya sisteminde gezinmek amacıyla genellikle girişte özel karakterler ve desenler kullanır. Standart tekniklerden bazıları şunlardır:
Java'daki potansiyel CWE-22 tehditlerini azaltmak, güvenli kodlama uygulamaları, giriş doğrulama ve uygun API kullanımının bir kombinasyonunu gerektirir. Bunun için önerilen stratejiler şunlardır:
Kanonlaştırma ve normalleştirme
Kullanmadan önce dosya yollarının normalleştirildiğinden emin olun. Java, geçiş saldırılarını azaltmaya yardımcı olabilecek yol normalleştirme yöntemleri sağlar.
import java.nio.file.Paths;
import java.nio.file.Path;
public File getFile(String fileName) throws IOException {
Path basePath = Paths.get("/var/www/uploads/");
Path filePath = basePath.resolve(fileName).normalize();
if (!filePath.startsWith(basePath)) {
throw new SecurityException("Attempted path traversal attack detected");
}
return filePath.toFile();
}
Giriş doğrulama ve temizleme
Kullanıcı girişinin titizlikle doğrulanmasını gerçekleştirin. ../, URL kodlu diziler veya diğer geçiş kalıpları gibi potansiyel olarak kötü amaçlı kalıplar içeren tüm girişleri reddedin.
public String sanitizeFileName(String fileName) {
if (fileName == null
|| fileName.contains("..")
|| fileName.contains("/")
|| fileName.contains("\")) {
throw new IllegalArgumentException("Invalid file name");
}
return fileName;
}
Beyaz liste yaklaşımı
Dosya adlarını bir dizi kabul edilebilir değer veya modele göre doğrulamak için beyaz liste kullanın. Bu, bilinen yıkıcı kalıpları kara listeye almaktan daha etkili olabilir.
public boolean isValidFileName(String fileName) {
return fileName.matches("[a-zA-Z0-9._-]+");
}
Güvenlik ve yetkilendirmelerden sorumlu
Dosya sistemine erişimi kısıtlamak için Java'nın güvenlik yöneticisini kullanın. Bu, çalışma zamanında erişim kontrolü ilkelerini uygulayarak ek bir koruma katmanı ekler. Ancak bu durumda, SecurityManager'ın gelecekteki JDK sürümlerinden birinde çıkarılacağından ilgili Java sürümünün dikkate alınması gerekir.
System.setSecurityManager(new SecurityManager());
Dosya erişim kontrolleri
Erişimi yalnızca gerekli dosya ve dizinlerle sınırlandırmak için sunucudaki dosya izinlerini kısıtlayın. Bu, potansiyel istismarların etkisini azaltır. Web servis süreci, hakları kesinlikle gerekli olanlarla sınırlı olan, tanımlanmış bir kullanıcı tarafından çalıştırılmalıdır.
Kayıt ve izleme
Şüpheli etkinlikleri tespit etmek ve bunlara yanıt vermek için kapsamlı günlük kaydı ve izleme uygulayın. Günlükler, potansiyel istismar girişimlerini takip etmek için yeterli ayrıntıyı yakalamalıdır.
import java.util.logging.Logger;
public class FileAccessLogger {
private static final Logger LOGGER =
Logger.getLogger(
FileAccessLogger.class.getName());
public void logAccessAttempt(String fileName) {
LOGGER.warning("Attempted access to file: " + fileName);
}
}
Örnek Olay: Savunmasız Bir Java Uygulaması
Bahsedilen düzeltme stratejilerinin uygulanmasını göstermek için varsayımsal bir vaka çalışmasını ele alalım. Kullanıcıların bir sunucudan dosya indirmesine olanak tanıyan basit bir Java web uygulamamız olduğunu varsayalım.
@WebServlet("/download")
public class FileDownloadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String fileName = request.getParameter("file");
File file = new File("/var/www/uploads/" + fileName);
if (file.exists()) {
FileInputStream fis = new FileInputStream(file);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment; filename="" + file.getName() + """);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
response.getOutputStream().write(buffer, 0, bytesRead);
}
fis.close();
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
}
Bu servlet parametreyi okur file istekten ve bir dosya oluşturur File-Nesne. Uygun doğrulama olmadan, bir saldırgan bu durumdan yararlanarak sunucudan rastgele dosyalar indirebilir.
@WebServlet("/download")
public class FileDownloadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String fileName = sanitizeFileName(request.getParameter("file"));
Path basePath = Paths.get("/var/www/uploads/");
Path filePath = basePath.resolve(fileName).normalize();
if (!filePath.startsWith(basePath)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid file path");
return;
}
File file = filePath.toFile();
if (file.exists()) {
FileInputStream fis = new FileInputStream(file);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment; filename="" + file.getName() + """);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
response.getOutputStream().write(buffer, 0, bytesRead);
}
fis.close();
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
private String sanitizeFileName(String fileName) {
if (fileName == null
|| fileName.contains("..")
|| fileName.contains("/")
|| fileName.contains("\")) {
throw new IllegalArgumentException("Invalid file name");
}
return fileName;
}
}
Güvenli sürümde yöntem şunları sağlar: sanitizeFileName dosya adının geçiş dizilerinden arınmış olmasını ve dizin geçişini önlemek için yolun normalleştirilmesini ve kontrol edilmesini sağlar.
CWE-22 (Yol Geçişi), uygun şekilde azaltılmadığı takdirde ciddi sonuçlara yol açabilecek kritik bir güvenlik açığıdır. Java uygulamalarında, bu tehdide karşı koruma sağlamak için güvenli kodlama uygulamaları, giriş doğrulama, kanonikleştirme ve erişim kontrollerinin bir kombinasyonunun kullanılması önemlidir. Geliştiriciler, CWE-22'nin doğasını anlayarak ve sağlam güvenlik önlemleri uygulayarak, yetkisiz dosya erişimi riskini önemli ölçüde azaltabilir ve uygulamalarını potansiyel istismardan koruyabilir.
Duyuru
Sven, 1996'dan bu yana ve 15 yılı aşkın bir süredir dünya çapında otomotiv, havacılık, sigorta, bankacılık, Birleşmiş Milletler ve Dünya Bankası gibi endüstrilerde endüstriyel projelerde Java programlıyor. 10 yıldan fazla bir süredir Amerika'dan Yeni Zelanda'ya kadar konferanslarda ve topluluk etkinliklerinde konuşmacı olarak yer alıyor, JFrog ve Vaadin için geliştirici savunucusu olarak çalışıyor ve düzenli olarak BT dergileri ve teknoloji portalları için makaleler yazıyor. Ana konusu olan Core Java'nın yanı sıra TDD ve güvenli kodlama uygulamalarını da kapsar.
Kısaca CWE-22
CWE-22, “Yol adının kısıtlı bir dizine uygunsuz şekilde kısıtlanması (Yol Geçişi)” olarak sınıflandırılmıştır. Güvenlik açığı, bir uygulamanın uygun doğrulama veya temizleme olmadan bir yol oluşturmak için kullanıcı girişini kullanması ve birinin amaçlanan dizinin dışına çıkan yolları belirlemesine izin vermesi durumunda ortaya çıkar. Dizin yapısında bir seviye yukarı çıkmak için ../ gibi diziler kullanılabilir.
Örneğin, kullanıcı girdisine dayalı olarak bir dosyayı okuyan tipik bir Java kod parçacığı şuna benzer:
String fileName = request.getParameter("file");
File file = new File("/var/www/uploads/" + fileName);
FileInputStream fis = new FileInputStream(file);
Bu parametre fileName Düzgün bir şekilde doğrulanmazsa, bir saldırgan, bir yol geçiş sırası (`. ./.. /etc/passwd) kullanarak /var/www/uploads/ dizini dışındaki dosyalara erişmek için onu değiştirebilir, örneğin: B. /etc/passwd `).
CWE-22'nin Etkisi
CWE-22'nin etkisi ciddi olabilir ve hassas dosyalara yetkisiz erişimden sistemin tamamen tehlikeye atılmasına kadar değişebilir. Olası etkiler şunları içerir:
- Hassas bilgilerin açığa çıkması: Saldırganlar yapılandırma dosyaları, şifreler ve kişisel bilgiler gibi hassas dosyalara erişebilir.
- Veri bütünlüğünün tehlikeye atılması: Saldırganlar dosyaları değiştirebilir, bu da potansiyel olarak verilerin bozulmasına veya kritik uygulama dosyalarının değiştirilmesine neden olabilir.
- Hizmet Reddi (DoS): Saldırganlar, sistem dosyalarına erişerek ve bunları değiştirerek normal işlemleri bozabilir.
- Rasgele kod yürütme: Aşırı durumlarda, saldırganlar yürütülebilir dosyalara veya komut dosyalarına erişim kazanırlarsa rasgele kod çalıştırabilirler.
Saldırgan, Yol Geçişi güvenlik açığından yararlanmak için dosya sisteminde gezinmek amacıyla genellikle girişte özel karakterler ve desenler kullanır. Standart tekniklerden bazıları şunlardır:
- Nokta-nokta-eğik çizgi (../): Saldırganın dizin yapısını yukarı taşımak için ../ kullandığı en yaygın yöntem.
- Kodlanmış karakterler: Saldırganlar, basit giriş filtrelerini atlamak için URL kodlamasını (%2e%2e%2f) veya diğer kodlama şemalarını kullanabilir.
- Sıfır Bayt Ekleme: Boş baytlar (%00) bazen dizeleri erken sonlandırmak için kullanılır; böylece eklenen yol uzantıları veya bileşenleri etkili bir şekilde göz ardı edilir.
Java'daki potansiyel CWE-22 tehditlerini azaltmak, güvenli kodlama uygulamaları, giriş doğrulama ve uygun API kullanımının bir kombinasyonunu gerektirir. Bunun için önerilen stratejiler şunlardır:
Kanonlaştırma ve normalleştirme
Kullanmadan önce dosya yollarının normalleştirildiğinden emin olun. Java, geçiş saldırılarını azaltmaya yardımcı olabilecek yol normalleştirme yöntemleri sağlar.
import java.nio.file.Paths;
import java.nio.file.Path;
public File getFile(String fileName) throws IOException {
Path basePath = Paths.get("/var/www/uploads/");
Path filePath = basePath.resolve(fileName).normalize();
if (!filePath.startsWith(basePath)) {
throw new SecurityException("Attempted path traversal attack detected");
}
return filePath.toFile();
}
Giriş doğrulama ve temizleme
Kullanıcı girişinin titizlikle doğrulanmasını gerçekleştirin. ../, URL kodlu diziler veya diğer geçiş kalıpları gibi potansiyel olarak kötü amaçlı kalıplar içeren tüm girişleri reddedin.
public String sanitizeFileName(String fileName) {
if (fileName == null
|| fileName.contains("..")
|| fileName.contains("/")
|| fileName.contains("\")) {
throw new IllegalArgumentException("Invalid file name");
}
return fileName;
}
Beyaz liste yaklaşımı
Dosya adlarını bir dizi kabul edilebilir değer veya modele göre doğrulamak için beyaz liste kullanın. Bu, bilinen yıkıcı kalıpları kara listeye almaktan daha etkili olabilir.
public boolean isValidFileName(String fileName) {
return fileName.matches("[a-zA-Z0-9._-]+");
}
Güvenlik ve yetkilendirmelerden sorumlu
Dosya sistemine erişimi kısıtlamak için Java'nın güvenlik yöneticisini kullanın. Bu, çalışma zamanında erişim kontrolü ilkelerini uygulayarak ek bir koruma katmanı ekler. Ancak bu durumda, SecurityManager'ın gelecekteki JDK sürümlerinden birinde çıkarılacağından ilgili Java sürümünün dikkate alınması gerekir.
System.setSecurityManager(new SecurityManager());
Dosya erişim kontrolleri
Erişimi yalnızca gerekli dosya ve dizinlerle sınırlandırmak için sunucudaki dosya izinlerini kısıtlayın. Bu, potansiyel istismarların etkisini azaltır. Web servis süreci, hakları kesinlikle gerekli olanlarla sınırlı olan, tanımlanmış bir kullanıcı tarafından çalıştırılmalıdır.
Kayıt ve izleme
Şüpheli etkinlikleri tespit etmek ve bunlara yanıt vermek için kapsamlı günlük kaydı ve izleme uygulayın. Günlükler, potansiyel istismar girişimlerini takip etmek için yeterli ayrıntıyı yakalamalıdır.
import java.util.logging.Logger;
public class FileAccessLogger {
private static final Logger LOGGER =
Logger.getLogger(
FileAccessLogger.class.getName());
public void logAccessAttempt(String fileName) {
LOGGER.warning("Attempted access to file: " + fileName);
}
}
Örnek Olay: Savunmasız Bir Java Uygulaması
Bahsedilen düzeltme stratejilerinin uygulanmasını göstermek için varsayımsal bir vaka çalışmasını ele alalım. Kullanıcıların bir sunucudan dosya indirmesine olanak tanıyan basit bir Java web uygulamamız olduğunu varsayalım.
@WebServlet("/download")
public class FileDownloadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String fileName = request.getParameter("file");
File file = new File("/var/www/uploads/" + fileName);
if (file.exists()) {
FileInputStream fis = new FileInputStream(file);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment; filename="" + file.getName() + """);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
response.getOutputStream().write(buffer, 0, bytesRead);
}
fis.close();
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
}
Bu servlet parametreyi okur file istekten ve bir dosya oluşturur File-Nesne. Uygun doğrulama olmadan, bir saldırgan bu durumdan yararlanarak sunucudan rastgele dosyalar indirebilir.
@WebServlet("/download")
public class FileDownloadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String fileName = sanitizeFileName(request.getParameter("file"));
Path basePath = Paths.get("/var/www/uploads/");
Path filePath = basePath.resolve(fileName).normalize();
if (!filePath.startsWith(basePath)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid file path");
return;
}
File file = filePath.toFile();
if (file.exists()) {
FileInputStream fis = new FileInputStream(file);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment; filename="" + file.getName() + """);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
response.getOutputStream().write(buffer, 0, bytesRead);
}
fis.close();
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
private String sanitizeFileName(String fileName) {
if (fileName == null
|| fileName.contains("..")
|| fileName.contains("/")
|| fileName.contains("\")) {
throw new IllegalArgumentException("Invalid file name");
}
return fileName;
}
}
Güvenli sürümde yöntem şunları sağlar: sanitizeFileName dosya adının geçiş dizilerinden arınmış olmasını ve dizin geçişini önlemek için yolun normalleştirilmesini ve kontrol edilmesini sağlar.
CWE-22 (Yol Geçişi), uygun şekilde azaltılmadığı takdirde ciddi sonuçlara yol açabilecek kritik bir güvenlik açığıdır. Java uygulamalarında, bu tehdide karşı koruma sağlamak için güvenli kodlama uygulamaları, giriş doğrulama, kanonikleştirme ve erişim kontrollerinin bir kombinasyonunun kullanılması önemlidir. Geliştiriciler, CWE-22'nin doğasını anlayarak ve sağlam güvenlik önlemleri uygulayarak, yetkisiz dosya erişimi riskini önemli ölçüde azaltabilir ve uygulamalarını potansiyel istismardan koruyabilir.