반응형

출처: https://www.owasp.org/index.php/Unvalidated_Redirects_and_Forwards_Cheat_Sheet


Safe URL Redirects

When we want to redirect a user automatically to another page (without an action of the visitor such as clicking on a hyperlink) you might implement a code such as the following:


// 안전한 URL 리다이렉트는 아래와 같이 명확한 주소를 사용하는 경우이다.

Java

 response.sendRedirect("http://www.mysite.com");

PHP

 <?php
 /* Redirect browser */
 header("Location: http://www.mysite.com/");
 ?>

ASP.NET

  Response.Redirect("~/folder/Login.aspx")

Rails

   redirect_to login_path

In the examples above, the URL is being explicitly declared in the code and cannot be manipulated by an attacker.

Dangerous URL Redirects

The following examples demonstrate unsafe redirect and forward code.

Dangerous URL Redirect Example 1

The following Java code receives the URL from the 'url' GET parameter and redirects to that URL.


//위험한 URL 리다이렉트는 아래와 같이 사용자로부터 받은 파라미터 정보를 URL을 그대로 리다이렉트 시켰을 경우이다.

 response.sendRedirect(request.getParameter("url"));

The following PHP code obtains a URL from the query string and then redirects the user to that URL.

 $redirect_url = $_GET['url'];
 header("Location: " . $redirect_url);
 

A similar example of C# .NET Vulnerable Code:

 string url = request.QueryString["url"];
 Response.Redirect(url);

And in rails:

  redirect_to params[:url]

The above code is vulnerable to an attack if no validation or extra method controls are applied to verify the certainty of the URL. This vulnerability could be used as part of a phishing scam by redirecting users to a malicious site. If no validation is applied, a malicious user could create a hyperlink to redirect your users to an unvalidated malicious website, for example:

 http://example.com/example.php?url=http://malicious.example.com

The user sees the link directing to the original trusted site (example.com) and does not realize the redirection that could take place

Dangerous URL Redirect Example 2

ASP.NET MVC 1 & 2 websites are particularly vulnerable to open redirection attacks. In order to avoid this vulnerability, you need to apply MVC 3.

The code for the LogOn action in an ASP.NET MVC 2 application is shown below. After a successful login, the controller returns a redirect to the returnUrl. You can see that no validation is being performed against the returnUrl parameter.

Listing 1 – ASP.NET MVC 2 LogOn action in AccountController.cs

 [HttpPost]
 public ActionResult LogOn(LogOnModel model, string returnUrl)
 {
   if (ModelState.IsValid)
   {
     if (MembershipService.ValidateUser(model.UserName, model.Password))
     {
       FormsService.SignIn(model.UserName, model.RememberMe);
       if (!String.IsNullOrEmpty(returnUrl))
       {
         return Redirect(returnUrl);
       }
       else
       {
         return RedirectToAction("Index", "Home");
       }
     }
     else
     {
       ModelState.AddModelError("", "The user name or password provided is incorrect.");
     }
   }

   // If we got this far, something failed, redisplay form
   return View(model);
 }

Dangerous Forward Example

When applications allow user input to forward requests between different parts of the site, the application must check that the user is authorized to access the url, perform the functions it provides, and it is an appropriate url request. If the application fails to perform these checks, an attacker crafted URL may pass the application’s access control check and then forward the attacker to an administrative function that is not normally permitted.

http://www.example.com/function.jsp?fwd=admin.jsp

The following code is a Java servlet that will receive a GET request with a url parameter in the request to forward to the address specified in the url parameter. The servlet will retrieve the url parameter value from the request and complete the server-side forward processing before responding to the browser.

public class ForwardServlet extends HttpServlet 
{
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String query = request.getQueryString();
    if (query.contains("fwd")) 
    {
      String fwd = request.getParameter("fwd");
      try 
      {
        request.getRequestDispatcher(fwd).forward(request, response);
      } 
      catch (ServletException e) 
      {
        e.printStackTrace();
      }
    }
  }
}


반응형

+ Recent posts