1

I apologize if this has already been asked but I've done quite a bit of searching and have not been able to find a question that is similar to mine yet.

On my application I have a password change page that triggers if a person is a new user or had his/her password reset.

The issue is that once the user makes changes and hits submit he/she gets redirected to the main page. Now if the user spams the back button a few times to get to the password change page they encounter an expired page and they can hit refresh. Then the browser asks the user to retry to submit the data. This submit request is a POST and the original data that the user entered previously can be seen in the packet.

I've only been able to replicate this issue on IE so far..tried it on FF and Chrome but nothing there.

My question is, is there a way, using jQuery, HTML, WSS, or otherwise-- to prevent this POST from being resubmitted? My biggest concern is the packet with the data that can be seen.

Thanks.

Tom Bascom
  • 13,405
  • 2
  • 27
  • 33
Silom
  • 35
  • 1
  • 6
  • What do you mean by "the data can be seen"? Where are you seeing it? – Barmar Oct 01 '15 at 23:03
  • And why can't they see it when they submit the original request? What's the difference between the original and the retry? – Barmar Oct 01 '15 at 23:04
  • The user can see the original form and are redirected to main page after clicking submit. But they can spam back a few times to the page and click retry. This sends a duplicate request that can be captured by wireshark. The user still errors out, he has to relog in, because the session is expired at that point. But I want to know if there's a way to prevent the request message from sending in the first place if the refresh+retry is used. -- The retry is an expired page that can resubmit data. – Silom Oct 02 '15 at 13:34
  • -- the resubmitted data doesn't change anything since the session id is invalid at that point, but the fact that the data can be seen is as a "security issue"..even though it's an https connection. – Silom Oct 02 '15 at 13:36
  • I'm still not understanding the distinction you're making. If they can capture the duplicate request with wireshark, why can't they also capture the original? – Barmar Oct 02 '15 at 14:33
  • And that's what I've been asking myself for the past week honestly. Our "security team" flagged it under OWASP A7 as "authorization bypass by forceful browsing..which is BS because the reauthentication fails and the user has to relogin anyway. Is there no way to clear this from cache so the second request sends nothing instead? – Silom Oct 02 '15 at 14:45
  • Does it matter if I also say that the issue can be replicated by logging out of the website and pressing back a few times or navigate to this expired page via broswer history? Is there a way to force clear the cache for IE after a user logs out? – Silom Oct 02 '15 at 14:51
  • AFAIK, there isn't any mechanism for applications to erase things from the browser's history. There are ways for you to detect resubmissions after the fact, but I don't think you can prevent them. – Barmar Oct 02 '15 at 14:51
  • I think you should try telling the security team that they're mistaken. Since you check the session variable, which was removed during the logout, there's no authorization bypass. – Barmar Oct 02 '15 at 14:53
  • Yes, I have before but I think I'll push back harder this time with concrete proof that there's no bypass anywhere here and the issue of the data being seen is a nonissue since an "intercepter" could get the first package in the first place. Thanks Barmar. – Silom Oct 02 '15 at 15:23

1 Answers1

2

A very general solution to this kind of problem is the Post/Redirect/Get-pattern.

What this means is that when you want to do a POST to a page that updates something in the background you really create two target pages:

Page number 1

The target page of the POST. Contains the logic for updating your database/filesystem/API or whatever needs to be done. This is just a URL without any real visual feedback, instead it redirect you to page number 2 (see below) once the logic is done. The redirect is a simple GET instead of a POST.

Page number 2

A page that shows you feedback of your action on "page number 1". Could be just a message "Password update OK" or actual data from the database or whatever suits you.

Now when somebody uses your form, they get posted to page number 1 that will perform the background action, then they are redirected to page number 2.

Now if they reload they wont redo the entire logic part but just the feedback-part.

Wikipedia has a pretty good explanation of this:

https://en.wikipedia.org/wiki/Post/Redirect/Get

How to do a redirect in Progress WebSpeed

In your outputHeader-procedure or where ever you do

output-content-type ("text/html":U).

Instead if the output-content-type: first do your logic and then insert something like this:

OUTPUT-HTTP-HEADER("Status", "301").
OUTPUT-HTTP-HEADER("Location","http://www.yoursite.com/newurl").
OUTPUT-HTTP-HEADER("","").

Now you will be server-side redirected once the logic has processed. You can also insert parameters in the url if needed:

DEFINE VARIABLE iId as INTEGER NO-UNDO.
OUTPUT-HTTP-HEADER("Status", "301").
OUTPUT-HTTP-HEADER("Location","http://www.yoursite.com/newurl?id=" + STRING(iId)).
OUTPUT-HTTP-HEADER("","").
Jensd
  • 7,886
  • 2
  • 28
  • 37
  • This doesn't work for me because the original problem is that the second post has data that I don't want to be captured. This PRG method is currently being used in the application right now also. – Silom Oct 02 '15 at 14:46
  • How is the redirect done? A proper 301 or something else like javascript/meta-tags? – Jensd Oct 03 '15 at 05:44
  • Javascript inside a WSS procedure – Silom Oct 05 '15 at 13:25
  • If you change it to a proper redirect you might solve the problem, I'll insert some code in my answer above. – Jensd Oct 05 '15 at 13:27
  • Same results, the POST request doesn't query the server with the data but it still shows up as a packet in wireshark..I don't think there is a way to prevent the request from resending from cache if the user clicks retry. At least not the way our application is being implemented.. Thanks for the suggestion though. – Silom Oct 05 '15 at 14:50
  • Maybe I'm missing something though. We might not be doing the PRG method. Our redirect is a procedure that is called using webspeed and using the onLoad="document.location = "myurl"" method though. I guess I don't know what kind of redirect that is or even if it's a redirect. – Silom Oct 06 '15 at 19:04
  • Its a javascript redirect on body load. Consider changing it! – Jensd Oct 06 '15 at 20:41
  • To the output-http-headers method? Also the stored procedure to redirect is on the same .html page as the rest of the WSS code, does that mean it's a different "page" or same "page"? I just don't know the scope of the application itself. Not very familiar with the way Progress uses webspeed servers. – Silom Oct 07 '15 at 14:32
  • First you run your update logic, then you redirect (with the code above) - you dont need to do anything else on this page. – Jensd Oct 08 '15 at 07:24
  • Okay I figured it out. Normally this solution would be the correct way to go. The caveat is that our implementation uses relative pathing to support legacy code. I had to stay with javascript, but I changed my on body load call from "document.location =" to "document.location.replace()" and everything works now. Thanks for all your help Jensd! – Silom Oct 08 '15 at 15:43