Skip to main content

Is there any need to sanitize a $_POST value before using it in a PHP header (for redirecting)


Can I use a posted value in a PHP redirect header safetly without checking it:




header( "Location: $base".$_POST['return'] ); // $base is set to the base of the site



(If the user would somehow manipulate return to a file that doesn't exist it would simply return a nice 404 message)



Is there any danger in doing this? Is there anything the user can set it to that can compromise the system or in any way do damage?


Source: Tips4allCCNA FINAL EXAM

Comments

  1. The header() function is no longer vulnerable to HTTP Response Splitting. The only vulnerability you have to worry about is OWASP a10 - unvalidated redirects and forwards.

    Providing a $base of anything other than the null string will prevent an attacker from forwarding a user to a remote domain, which could be useful for Phishing. Redirecting to the same domain could be useful to the attacker if are checking the referer as a form of CSRF prevention, but that is a weak form of protection that you really shouldn't be using anyway. Even with a base, the attacker can change the path by supplied a value like: /../../../admin.php, but this is still relative to the originating domain which in most cases is safe.

    One great way to deal with unvalidated redirects is to avoid the problem entirely by not using a REQUEST variable. Instead store it in a $_SESSION['redirect'], and use that for the next request. To be a bit more robust, you could say $_SESSION['redirect_checkout'], or something page specific.

    Another option is to use a white list, create a list of all values you would like to accept, and make sure the user supplied value is in your list.

    ReplyDelete
  2. Yes, absolutely! Don't trust any $_GET or $_POST values anytime!

    Suppose a third party site posts the form. It may post whatever address.

    A simple solution would be not to include the address, but a md5() hash of the address into the form. Once the form gets posted, it's the task of your script to map the hash to an actual address and then emit the Location header.

    My other post might be of interest.

    You might argue, that your app is bullet-proof. Why shouldn't I pass an URL directly?

    In fact, even well-designed applications aren't that bullet-proof. Step back and try to remember your last 'Ah, I forgot something. Let's fix it' event.

    Did you check at each point control each and any condition?


    User clicks on a web-form submit-button twice. Thus controller runs twice.
    User presses F5 an resubmits the last updating controller twice.
    User somehow manipulated parameters and a controller gets called with off values passed in.


    Therefore, I propose to not pass links or other parameters directly or unprotected / unvalidated.

    @Col. Shrapnel: I'm fully aware, that any URL at any point could be submitted to a web-app. That's trivial.

    Nevertheless, at a given point of control flow, there are certain acceptable next states of control flow.

    To ensure, that only those next control-flow states get reached, I propose to validate.

    A more general approach

    In fact, my recently updated internal framework never passes any parameters as GET or POST parameters from request to request. All parameters are saved and retrieved from a user session [inside a so called Flow, a part of a bigger control flow].

    Using the framework, only one single parameter - the FlowID - gets passed around. If the framework doesn't find the FlowID in the session's flow-store, the framework throws an exception and the dispatcher emits an error message.

    ReplyDelete
  3. XSS and SQL injection rules go here.

    Your URL contains a base, but that doesn't mean an attacker can craft a form that redirects to some page where you display or process data from the URL, or to a page where you use the URL as database input.

    ReplyDelete
  4. I upvoted Stefan's answer.

    I also have this to add. I wrote a nice class for building and parsing URLs. You could use it for validation, if you'd like.

    See Url.php and UrlTest.php for usage.

    https://github.com/homer6/altumo/tree/master/source/php/String

    Hope that helps...

    ReplyDelete

Post a Comment

Popular posts from this blog

[韓日関係] 首相含む大幅な内閣改造の可能性…早ければ来月10日ごろ=韓国

div not scrolling properly with slimScroll plugin

I am using the slimScroll plugin for jQuery by Piotr Rochala Which is a great plugin for nice scrollbars on most browsers but I am stuck because I am using it for a chat box and whenever the user appends new text to the boxit does scroll using the .scrollTop() method however the plugin's scrollbar doesnt scroll with it and when the user wants to look though the chat history it will start scrolling from near the top. I have made a quick demo of my situation http://jsfiddle.net/DY9CT/2/ Does anyone know how to solve this problem?

Why does this javascript based printing cause Safari to refresh the page?

The page I am working on has a javascript function executed to print parts of the page. For some reason, printing in Safari, causes the window to somehow update. I say somehow, because it does not really refresh as in reload the page, but rather it starts the "rendering" of the page from start, i.e. scroll to top, flash animations start from 0, and so forth. The effect is reproduced by this fiddle: http://jsfiddle.net/fYmnB/ Clicking the print button and finishing or cancelling a print in Safari causes the screen to "go white" for a sec, which in my real website manifests itself as something "like" a reload. While running print button with, let's say, Firefox, just opens and closes the print dialogue without affecting the fiddle page in any way. Is there something with my way of calling the browsers print method that causes this, or how can it be explained - and preferably, avoided? P.S.: On my real site the same occurs with Chrome. In the ex