বসন্ত 5.0.3 অনুরোধআরেক্টেড এক্সেক্সশন: অনুরোধটি প্রত্যাখ্যান করা হয়েছিল কারণ URL টি সাধারণ করা হয়নি


89

স্প্রিং 5.0.3 সহ এটি কোনও বাগ বা আমার শেষে জিনিসগুলি ঠিক করার জন্য একটি নতুন বৈশিষ্ট্য কিনা তা নিশ্চিত নয় Not

আপগ্রেড করার পরে, আমি এই ত্রুটিটি পাচ্ছি। মজার বিষয় হচ্ছে এই ত্রুটিটি কেবলমাত্র আমার স্থানীয় মেশিনে। এইচটিটিপিএস প্রোটোকল সহ পরীক্ষার পরিবেশে একই কোড সূক্ষ্মভাবে কাজ করে।

অবিরত ...

কারণ পরিসমাপ্তি JSP পৃষ্ঠাটি লোড জন্য আমার URL টি কারনেই আমি এই ত্রুটি পাচ্ছি হয় /location/thisPage.jsp। মূল্যায়ন কোডটি request.getRequestURI()আমাকে ফলাফল দেয় /WEB-INF/somelocation//location/thisPage.jsp। আমি যদি এটিতে জেএসপি পৃষ্ঠার ইউআরএল ঠিক করি তবে location/thisPage.jspজিনিসগুলি ভাল কাজ করে।

সুতরাং আমার প্রশ্নটি হল, আমি কোডের পথে /থেকে সরানো উচিত JSPকারণ এটিই এগিয়ে যাওয়ার দরকার। অথবা Springএকটি বাগ চালু করেছে হিসাবে আমার মেশিন এবং পরীক্ষা পরিবেশ মধ্যে একমাত্র পার্থক্য প্রোটোকল HTTPবনাম HTTPS

 org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL was not normalized.
    at org.springframework.security.web.firewall.StrictHttpFirewall.getFirewalledRequest(StrictHttpFirewall.java:123)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:194)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)


4
ইস্যুটি 5.1.0 এ সমাধান করার পরিকল্পনা করা হয়েছে; বর্তমানে 5.0.0 এ সমস্যা নেই।
java_dude

উত্তর:


73

স্প্রিং সিকিউরিটি ডকুমেন্টেশন অনুরোধে // ব্লক করার কারণ উল্লেখ করেছে।

উদাহরণস্বরূপ, এটিতে প্যাথ-ট্র্যাভারসাল সিকোয়েন্সগুলি (যেমন /../) বা একাধিক ফরোয়ার্ড স্ল্যাশ (//) থাকতে পারে যা প্যাটার্ন-ম্যাচগুলি ব্যর্থ হতে পারে। কিছু পাত্রে সার্লেলেট ম্যাপিংয়ের আগে এগুলি স্বাভাবিক করা হয়, তবে অন্যরা তা করে না। এই জাতীয় সমস্যা থেকে রক্ষা করতে, ফিল্টারচেইনপ্রক্সি অনুরোধটি যাচাই করতে এবং মোড়ানোর জন্য একটি এইচটিটিপিফায়ারওয়াল কৌশল ব্যবহার করে। অ-সাধারণীকরণের অনুরোধগুলি ডিফল্টরূপে স্বয়ংক্রিয়ভাবে প্রত্যাখ্যাত হয় এবং পাথ প্যারামিটার এবং সদৃশ স্ল্যাশগুলি মিলে যাওয়ার উদ্দেশ্যে সরিয়ে ফেলা হয়।

সুতরাং দুটি সম্ভাব্য সমাধান রয়েছে -

  1. ডাবল স্ল্যাশ সরান (পছন্দসই পদ্ধতির)
  2. নীচের কোডটি ব্যবহার করে স্ট্রাইকএইচটিপিফায়ারওয়ালটি কাস্টমাইজ করে বসন্ত সুরক্ষায় // কে অনুমতি দিন।

পদক্ষেপ 1 কাস্টম ফায়ারওয়াল তৈরি করুন যা URL এ স্ল্যাশ দেয়।

@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
    StrictHttpFirewall firewall = new StrictHttpFirewall();
    firewall.setAllowUrlEncodedSlash(true);    
    return firewall;
}

পদক্ষেপ 2 এবং তারপরে ওয়েব সিকিউরিটিতে এই বিনকে কনফিগার করুন

@Override
public void configure(WebSecurity web) throws Exception {
    //@formatter:off
    super.configure(web);
    web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
....
}

পদক্ষেপ 2 একটি alচ্ছিক পদক্ষেপ, স্প্রিং বুট কেবল প্রকারের ঘোষিত হওয়ার জন্য একটি শিম প্রয়োজন HttpFirewallএবং এটি ফিল্টার চেইনে এটি স্বয়ংক্রিয়ভাবে কনফিগার করবে।

স্প্রিং সিকিউরিটি 5.4 আপডেট

স্প্রিং সুরক্ষা ৫.৪ এবং তার উপরে (স্প্রিং বুট> = ২.৪.০) তে, আমরা নীচের শিমটি তৈরি করে অনুরোধ প্রত্যাখ্যান করা সম্পর্কে অভিযোগ করা প্রচুর লগ থেকে মুক্তি পেতে পারি।

import org.springframework.security.web.firewall.RequestRejectedHandler;
import org.springframework.security.web.firewall.HttpStatusRequestRejectedHandler;

@Bean
RequestRejectedHandler requestRejectedHandler() {
   return new HttpStatusRequestRejectedHandler();
}

হ্যাঁ পথ-ট্র্যাভারসাল সুরক্ষা চালু করা হয়েছে। একটি নতুন বৈশিষ্ট্য রয়েছে এবং এটি সমস্যার কারণ হতে পারে। যা আমি খুব নিশ্চিত নই আপনি যেমন দেখেন এটি HTTPS এ কাজ করে HTTP তে নয়। এই বাগটি সমাধান না হওয়া পর্যন্ত আমি অপেক্ষা করব jira.spring.io/browse/SPR-16419
java_dude

খুব সম্ভবত আমাদের সমস্যাটির অংশ ... তবে ... ব্যবহারকারী কোনও // টাইপ করছে না তাই আমি কীভাবে দ্বিতীয় / প্রথম স্থানে যুক্ত হচ্ছে তা জানার চেষ্টা করছি ... যদি বসন্ত আমাদের উৎপন্ন করে jstl url এটিকে যুক্ত করা উচিত নয়, বা যুক্ত করার পরে এটি স্বাভাবিক করা উচিত।
xenoterracide

4
এটি প্রকৃতপক্ষে সমাধানটি সমাধান করে না, অন্তত স্প্রিং সিকিউরিটি 5.1.1 এর জন্য। আপনার যদি একটি / বি // সি এর মতো দুটি স্ল্যাশ সহ ইউআরএল প্রয়োজন হয় তবে আপনাকে ডিফল্ট এইচটিএফপিওয়্যারওয়াল ব্যবহার করতে হবে। ইসরমালাইজড পদ্ধতিটি স্ট্রাইকএইচটিপিফায়ারওয়ালে কনফিগার করা বা ওভাররাইড করা যায় না।
জেসন উইনিবেক 21

বসার একা বুটের বিপরীতে কীভাবে এটি করা যায় সে সম্পর্কে কেউ সুযোগ দিতে পারে?
স্কচুন

29

setAllowUrlEncodedSlash(true)আমার জন্য কাজ করেনি। ডাবল স্ল্যাশ থাকার পরেও অভ্যন্তরীণ পদ্ধতি isNormalizedফিরে falseআসে।

আমি প্রতিস্থাপিত StrictHttpFirewallসঙ্গে DefaultHttpFirewallকেবলমাত্র নিচের কোড না থাকার:

@Bean
public HttpFirewall defaultHttpFirewall() {
    return new DefaultHttpFirewall();
}

আমার জন্য ভাল কাজ করছি।
ব্যবহার করে কোন ঝুঁকি DefaultHttpFirewall?


4
হ্যাঁ. কেবলমাত্র আপনি আপনার রুমমেটের জন্য অতিরিক্ত কী তৈরি করতে পারবেন না, এর অর্থ এই নয় যে আপনার একমাত্র চাবিটি ডোরমেটের নীচে রাখা উচিত। পরামর্শ দেওয়া হয়নি। সুরক্ষা পরিবর্তন করা উচিত নয়।
java_dude

18
@ জাভা_ডুড দুর্দান্ত আপনি কীভাবে কোনও তথ্য বা যুক্তি সরবরাহ করেন নি, কেবল একটি অস্পষ্ট উপমা।
কাকাকোও

আর একটি বিকল্প হ'ল এই উত্তরেStrictHttpFirewall বর্ণিত হিসাবে ইউআরএলগুলি প্রত্যাখ্যান করার ক্ষেত্রে কিছুটা আরও নিয়ন্ত্রণ দেওয়ার জন্য সাবক্লাস ।
vallismortis

4
এটি আমার পক্ষে কাজ করেছে তবে আমি এটি আমার মটরশুটি এক্সএমএলতেও যুক্ত করতে <sec:http-firewall ref="defaultHttpFirewall"/>
পেরেছিলাম

4
এই সমাধানটি ব্যবহারের কী কী প্রভাব পড়বে?
ফিলিপ দেশীদারতীয়

10

আমি একই সমস্যার সাথে:

স্প্রিং বুট সংস্করণ = 1.5.10
স্প্রিং সিকিউরিটি সংস্করণ = 4.2.4


ModelAndViewশেষের পয়েন্টগুলিতে সমস্যা দেখা দিয়েছে, যেখানে ভিউনামটি পূর্ববর্তী ফরোয়ার্ড স্ল্যাশ দিয়ে সংজ্ঞায়িত করা হয়েছিল । উদাহরণ:

ModelAndView mav = new ModelAndView("/your-view-here");

যদি আমি স্ল্যাশটি সরিয়ে ফেলি তবে এটি ঠিক আছে। উদাহরণ:

ModelAndView mav = new ModelAndView("your-view-here");

আমি রেডাইরেক্টভিউয়ের সাথেও কিছু পরীক্ষা করেছি এবং মনে হয় এটি পূর্ববর্তী ফরোয়ার্ড স্ল্যাশ নিয়ে কাজ করে।


4
সমাধান না। যদি এটি বসন্তের দিকের বাগ হয়। যদি তারা এটি পরিবর্তন করে তবে আপনাকে আবার সমস্ত পরিবর্তন পূর্বাবস্থায় ফিরিয়ে আনতে হবে। ততক্ষণে এটি সমাধান হওয়ার জন্য চিহ্নিত হিসাবে আমি 5.1 অবধি অপেক্ষা করব।
java_dude

4
না আপনাকে পরিবর্তনটি ফিরিয়ে আনতে হবে না কারণ পূর্ববর্তী সংস্করণগুলিতে ফরোয়ার্ড স্ল্যাশের পূর্ববর্তী ছাড়াই ভিউনামটি সংজ্ঞায়িত করা ভাল কাজ করে।
টর্স্টেন ওজাপেরভে

সমস্যাটি হ'ল ঠিক তাই। যদি এটি ঠিকঠাক কাজ করে এবং আপনি কোনও পরিবর্তন না করেন তবে স্প্রিং একটি বাগ প্রবর্তন করেছে। পথ সর্বদা "/" দিয়ে শুরু করা উচিত। কোনও বসন্তের ডকুমেন্টেশন চেকআউট করুন। এগুলি github.com/spring-projects/spring-security/issues/5007 & github.com/spring-projects/spring-security/issues/5044
java_dude

4
এই বিট আমাকে। অগ্রণী '/' ছাড়াই সমস্ত মডেলঅ্যান্ডভিউ আপডেট করা সমস্যার সমাধান করে
নাথান পেরিয়ার

jira.spring.io/browse/SPR-16740 আমি একটি ত্রুটি খুলেছি, তবে নেতৃত্বটি সরিয়ে দেওয়া / আমার পক্ষে ঠিক করা হয়নি, এবং বেশিরভাগ ক্ষেত্রে আমরা কেবল ভিউটির নামটি স্ট্রিং হিসাবে ফিরিয়ে আছি (নিয়ন্ত্রকের কাছ থেকে) । সমাধান হিসাবে পুনঃনির্দেশিত দৃষ্টিতে নজর দেওয়া দরকার।
xenoterracide

6

একবার আমি এপিআই কল করার সময় ডাবল স্ল্যাশ ব্যবহার করেছি তখন আমি একই ত্রুটি পেয়েছি।

আমাকে http: // লোকালহোস্ট: 8080 / getSomething কল করতে হয়েছিল তবে আমি http: // লোকালহোস্ট: 8080 // getSomething পছন্দ করেছি । আমি অতিরিক্ত স্ল্যাশ সরিয়ে এটি সমাধান করেছি।


আমরা কি এর জন্য কিছু ব্যতিক্রম হ্যান্ডলিং লিখতে পারি যাতে আমরা ক্লায়েন্টকে তার ভুল ইনপুট সম্পর্কে অবহিত করতে পারি?
আশ্চর্যজনক

5

আমার ক্ষেত্রে, বসন্ত-সেকুরি-ওয়েব 3.1.3 থেকে 4.2.12 এ আপগ্রেড করা হয়েছে, এটিকে ডিফল্টরূপে defaultHttpFirewallপরিবর্তন DefaultHttpFirewallকরা StrictHttpFirewallহয়েছিল। সুতরাং এটি কেবল নীচের মত এক্সএমএল কনফিগারেশনে সংজ্ঞায়িত করুন:

<bean id="defaultHttpFirewall" class="org.springframework.security.web.firewall.DefaultHttpFirewall"/>
<sec:http-firewall ref="defaultHttpFirewall"/>

HTTPFirewallহিসাবে সেট করুনDefaultHttpFirewall


4
কী চলছে এবং কেন চলছে তা ব্যাখ্যা করে আপনার কোডটিতে কিছু বর্ণনা যুক্ত করুন। এটি ভাল অনুশীলন। আপনি যদি তা না করেন তবে আপনার উত্তর মোছার ঝুঁকিতে রয়েছে। এটি ইতিমধ্যে নিম্নমানের হিসাবে পতাকাঙ্কিত হয়েছে।
হার্ববিস্কফ

3

সমাধানের নীচে প্রায় একটি পরিষ্কার কাজ I এটি সুরক্ষার সাথে আপস করে না কারণ আমরা একই কঠোর ফায়ারওয়াল ব্যবহার করছি।

ফিক্সিংয়ের পদক্ষেপগুলি নীচের মতো:

পদক্ষেপ 1: নীচের মতো স্ট্রাইকট এইচটিপি ফায়ারওয়ালকে ওভাররাইড করে একটি ক্লাস তৈরি করুন ।

package com.biz.brains.project.security.firewall;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.HttpMethod;
import org.springframework.security.web.firewall.DefaultHttpFirewall;
import org.springframework.security.web.firewall.FirewalledRequest;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.RequestRejectedException;

public class CustomStrictHttpFirewall implements HttpFirewall {
    private static final Set<String> ALLOW_ANY_HTTP_METHOD = Collections.unmodifiableSet(Collections.emptySet());

    private static final String ENCODED_PERCENT = "%25";

    private static final String PERCENT = "%";

    private static final List<String> FORBIDDEN_ENCODED_PERIOD = Collections.unmodifiableList(Arrays.asList("%2e", "%2E"));

    private static final List<String> FORBIDDEN_SEMICOLON = Collections.unmodifiableList(Arrays.asList(";", "%3b", "%3B"));

    private static final List<String> FORBIDDEN_FORWARDSLASH = Collections.unmodifiableList(Arrays.asList("%2f", "%2F"));

    private static final List<String> FORBIDDEN_BACKSLASH = Collections.unmodifiableList(Arrays.asList("\\", "%5c", "%5C"));

    private Set<String> encodedUrlBlacklist = new HashSet<String>();

    private Set<String> decodedUrlBlacklist = new HashSet<String>();

    private Set<String> allowedHttpMethods = createDefaultAllowedHttpMethods();

    public CustomStrictHttpFirewall() {
        urlBlacklistsAddAll(FORBIDDEN_SEMICOLON);
        urlBlacklistsAddAll(FORBIDDEN_FORWARDSLASH);
        urlBlacklistsAddAll(FORBIDDEN_BACKSLASH);

        this.encodedUrlBlacklist.add(ENCODED_PERCENT);
        this.encodedUrlBlacklist.addAll(FORBIDDEN_ENCODED_PERIOD);
        this.decodedUrlBlacklist.add(PERCENT);
    }

    public void setUnsafeAllowAnyHttpMethod(boolean unsafeAllowAnyHttpMethod) {
        this.allowedHttpMethods = unsafeAllowAnyHttpMethod ? ALLOW_ANY_HTTP_METHOD : createDefaultAllowedHttpMethods();
    }

    public void setAllowedHttpMethods(Collection<String> allowedHttpMethods) {
        if (allowedHttpMethods == null) {
            throw new IllegalArgumentException("allowedHttpMethods cannot be null");
        }
        if (allowedHttpMethods == ALLOW_ANY_HTTP_METHOD) {
            this.allowedHttpMethods = ALLOW_ANY_HTTP_METHOD;
        } else {
            this.allowedHttpMethods = new HashSet<>(allowedHttpMethods);
        }
    }

    public void setAllowSemicolon(boolean allowSemicolon) {
        if (allowSemicolon) {
            urlBlacklistsRemoveAll(FORBIDDEN_SEMICOLON);
        } else {
            urlBlacklistsAddAll(FORBIDDEN_SEMICOLON);
        }
    }

    public void setAllowUrlEncodedSlash(boolean allowUrlEncodedSlash) {
        if (allowUrlEncodedSlash) {
            urlBlacklistsRemoveAll(FORBIDDEN_FORWARDSLASH);
        } else {
            urlBlacklistsAddAll(FORBIDDEN_FORWARDSLASH);
        }
    }

    public void setAllowUrlEncodedPeriod(boolean allowUrlEncodedPeriod) {
        if (allowUrlEncodedPeriod) {
            this.encodedUrlBlacklist.removeAll(FORBIDDEN_ENCODED_PERIOD);
        } else {
            this.encodedUrlBlacklist.addAll(FORBIDDEN_ENCODED_PERIOD);
        }
    }

    public void setAllowBackSlash(boolean allowBackSlash) {
        if (allowBackSlash) {
            urlBlacklistsRemoveAll(FORBIDDEN_BACKSLASH);
        } else {
            urlBlacklistsAddAll(FORBIDDEN_BACKSLASH);
        }
    }

    public void setAllowUrlEncodedPercent(boolean allowUrlEncodedPercent) {
        if (allowUrlEncodedPercent) {
            this.encodedUrlBlacklist.remove(ENCODED_PERCENT);
            this.decodedUrlBlacklist.remove(PERCENT);
        } else {
            this.encodedUrlBlacklist.add(ENCODED_PERCENT);
            this.decodedUrlBlacklist.add(PERCENT);
        }
    }

    private void urlBlacklistsAddAll(Collection<String> values) {
        this.encodedUrlBlacklist.addAll(values);
        this.decodedUrlBlacklist.addAll(values);
    }

    private void urlBlacklistsRemoveAll(Collection<String> values) {
        this.encodedUrlBlacklist.removeAll(values);
        this.decodedUrlBlacklist.removeAll(values);
    }

    @Override
    public FirewalledRequest getFirewalledRequest(HttpServletRequest request) throws RequestRejectedException {
        rejectForbiddenHttpMethod(request);
        rejectedBlacklistedUrls(request);

        if (!isNormalized(request)) {
            request.setAttribute("isNormalized", new RequestRejectedException("The request was rejected because the URL was not normalized."));
        }

        String requestUri = request.getRequestURI();
        if (!containsOnlyPrintableAsciiCharacters(requestUri)) {
            request.setAttribute("isNormalized",  new RequestRejectedException("The requestURI was rejected because it can only contain printable ASCII characters."));
        }
        return new FirewalledRequest(request) {
            @Override
            public void reset() {
            }
        };
    }

    private void rejectForbiddenHttpMethod(HttpServletRequest request) {
        if (this.allowedHttpMethods == ALLOW_ANY_HTTP_METHOD) {
            return;
        }
        if (!this.allowedHttpMethods.contains(request.getMethod())) {
            request.setAttribute("isNormalized",  new RequestRejectedException("The request was rejected because the HTTP method \"" +
                    request.getMethod() +
                    "\" was not included within the whitelist " +
                    this.allowedHttpMethods));
        }
    }

    private void rejectedBlacklistedUrls(HttpServletRequest request) {
        for (String forbidden : this.encodedUrlBlacklist) {
            if (encodedUrlContains(request, forbidden)) {
                request.setAttribute("isNormalized",  new RequestRejectedException("The request was rejected because the URL contained a potentially malicious String \"" + forbidden + "\""));
            }
        }
        for (String forbidden : this.decodedUrlBlacklist) {
            if (decodedUrlContains(request, forbidden)) {
                request.setAttribute("isNormalized",  new RequestRejectedException("The request was rejected because the URL contained a potentially malicious String \"" + forbidden + "\""));
            }
        }
    }

    @Override
    public HttpServletResponse getFirewalledResponse(HttpServletResponse response) {
        return new FirewalledResponse(response);
    }

    private static Set<String> createDefaultAllowedHttpMethods() {
        Set<String> result = new HashSet<>();
        result.add(HttpMethod.DELETE.name());
        result.add(HttpMethod.GET.name());
        result.add(HttpMethod.HEAD.name());
        result.add(HttpMethod.OPTIONS.name());
        result.add(HttpMethod.PATCH.name());
        result.add(HttpMethod.POST.name());
        result.add(HttpMethod.PUT.name());
        return result;
    }

    private static boolean isNormalized(HttpServletRequest request) {
        if (!isNormalized(request.getRequestURI())) {
            return false;
        }
        if (!isNormalized(request.getContextPath())) {
            return false;
        }
        if (!isNormalized(request.getServletPath())) {
            return false;
        }
        if (!isNormalized(request.getPathInfo())) {
            return false;
        }
        return true;
    }

    private static boolean encodedUrlContains(HttpServletRequest request, String value) {
        if (valueContains(request.getContextPath(), value)) {
            return true;
        }
        return valueContains(request.getRequestURI(), value);
    }

    private static boolean decodedUrlContains(HttpServletRequest request, String value) {
        if (valueContains(request.getServletPath(), value)) {
            return true;
        }
        if (valueContains(request.getPathInfo(), value)) {
            return true;
        }
        return false;
    }

    private static boolean containsOnlyPrintableAsciiCharacters(String uri) {
        int length = uri.length();
        for (int i = 0; i < length; i++) {
            char c = uri.charAt(i);
            if (c < '\u0020' || c > '\u007e') {
                return false;
            }
        }

        return true;
    }

    private static boolean valueContains(String value, String contains) {
        return value != null && value.contains(contains);
    }

    private static boolean isNormalized(String path) {
        if (path == null) {
            return true;
        }

        if (path.indexOf("//") > -1) {
            return false;
        }

        for (int j = path.length(); j > 0;) {
            int i = path.lastIndexOf('/', j - 1);
            int gap = j - i;

            if (gap == 2 && path.charAt(i + 1) == '.') {
                // ".", "/./" or "/."
                return false;
            } else if (gap == 3 && path.charAt(i + 1) == '.' && path.charAt(i + 2) == '.') {
                return false;
            }

            j = i;
        }

        return true;
    }

}

পদক্ষেপ 2: একটি ফায়ারওয়ালেড রেসপন্স ক্লাস তৈরি করুন

package com.biz.brains.project.security.firewall;

import java.io.IOException;
import java.util.regex.Pattern;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

class FirewalledResponse extends HttpServletResponseWrapper {
    private static final Pattern CR_OR_LF = Pattern.compile("\\r|\\n");
    private static final String LOCATION_HEADER = "Location";
    private static final String SET_COOKIE_HEADER = "Set-Cookie";

    public FirewalledResponse(HttpServletResponse response) {
        super(response);
    }

    @Override
    public void sendRedirect(String location) throws IOException {
        // TODO: implement pluggable validation, instead of simple blacklisting.
        // SEC-1790. Prevent redirects containing CRLF
        validateCrlf(LOCATION_HEADER, location);
        super.sendRedirect(location);
    }

    @Override
    public void setHeader(String name, String value) {
        validateCrlf(name, value);
        super.setHeader(name, value);
    }

    @Override
    public void addHeader(String name, String value) {
        validateCrlf(name, value);
        super.addHeader(name, value);
    }

    @Override
    public void addCookie(Cookie cookie) {
        if (cookie != null) {
            validateCrlf(SET_COOKIE_HEADER, cookie.getName());
            validateCrlf(SET_COOKIE_HEADER, cookie.getValue());
            validateCrlf(SET_COOKIE_HEADER, cookie.getPath());
            validateCrlf(SET_COOKIE_HEADER, cookie.getDomain());
            validateCrlf(SET_COOKIE_HEADER, cookie.getComment());
        }
        super.addCookie(cookie);
    }

    void validateCrlf(String name, String value) {
        if (hasCrlf(name) || hasCrlf(value)) {
            throw new IllegalArgumentException(
                    "Invalid characters (CR/LF) in header " + name);
        }
    }

    private boolean hasCrlf(String value) {
        return value != null && CR_OR_LF.matcher(value).find();
    }
}

ধাপ 3: দমন করতে একটি কাস্টম ফিল্টার তৈরি RejectedException

package com.biz.brains.project.security.filter;

import java.io.IOException;
import java.util.Objects;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.security.web.firewall.RequestRejectedException;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestRejectedExceptionFilter extends GenericFilterBean {

        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            try {
                RequestRejectedException requestRejectedException=(RequestRejectedException) servletRequest.getAttribute("isNormalized");
                if(Objects.nonNull(requestRejectedException)) {
                    throw requestRejectedException;
                }else {
                    filterChain.doFilter(servletRequest, servletResponse);
                }
            } catch (RequestRejectedException requestRejectedException) {
                HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
                HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
                log
                    .error(
                            "request_rejected: remote={}, user_agent={}, request_url={}",
                            httpServletRequest.getRemoteHost(),  
                            httpServletRequest.getHeader(HttpHeaders.USER_AGENT),
                            httpServletRequest.getRequestURL(), 
                            requestRejectedException
                    );

                httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
            }
        }
}

পদক্ষেপ 4: সুরক্ষা কনফিগারেশনে স্প্রিং ফিল্টার চেইনে কাস্টম ফিল্টার যুক্ত করুন

@Override
protected void configure(HttpSecurity http) throws Exception {
     http.addFilterBefore(new RequestRejectedExceptionFilter(),
             ChannelProcessingFilter.class);
}

এখন উপরের ফিক্সটি ব্যবহার করে আমরা RequestRejectedException404 পৃষ্ঠা ত্রুটি সহ পরিচালনা করতে পারি ।


ধন্যবাদ. সামনের দিকের অ্যাপ্লিকেশনগুলি সমস্ত আপগ্রেড না করা পর্যন্ত আমাদের জাভা মাইক্রোসার্চিসকে আপগ্রেড করার অনুমতি দেওয়ার জন্য আমি এই পদ্ধতির ব্যবহার করেছি। '//' সাফল্যের সাথে স্বাভাবিক হিসাবে বিবেচনা করার অনুমতি দেওয়ার জন্য আমার 3 এবং 4 পদক্ষেপের দরকার নেই। আমি কেবলমাত্র সেই শর্তটি মন্তব্য করেছি যা ইসরমালাইজডে ডাবল-স্ল্যাশের জন্য পরীক্ষা করেছে এবং তারপরে কাস্টমস্ট্রিটএইচটিপিফায়ারওয়াল ক্লাসটি ব্যবহার করার জন্য একটি বিনকে কনফিগার করেছে।
gtaborga

কনফিগারেশনের মাধ্যমে কি আরও সহজ কাজ হতে পারে? তবে ফায়ারওয়ালটি বন্ধ না করে ..
প্রথমেশ ধনওয়াড

0

আমার ক্ষেত্রে, পোস্টম্যানের সাথে লগ ইন না হওয়ার কারণে সমস্যাটি দেখা দিয়েছে, তাই আমি আমার ক্রোম সেশনে শিরোনামগুলি থেকে সেশন কুকি নিয়ে অন্য ট্যাবে একটি সংযোগ খুলেছি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.