Users requesting GET when my form method is POST - asp.net-mvc

I'm seeing an intermittent problem on our web site. Some users are trying to submit forms via GET when my form method is POST. The errors always come from IE users. I have noticed a few UA strings have a reference to "yie8," which I am assuming is Yahoo's IE8 package. I think the Yahoo! toolbar might have something against me, but I can't replicate the problem on IE7 with the toolbar installed. The problem happens not only on this form, but various others, many of which are submitted via Ajax using the jQuery form plugin load() function with an object parameter passed. This example isn't one of those.
A simple fix would be to just take out all of my AcceptVerb() attributes, but that would be totally lame. Anyone ever come across something like this or have any ideas with dealing with it?
Here's an example exception log entry.
We've got a Web problem! Exception thrown:
http://my.web.site/User.mvc/ResetPassword
Method: GET
User: <not logged in>
UserAgent: IE 7 (Mozilla/4.0 (compatible; MSIE 7.0;Windows NT 5.1;.NET CLR 1.1.4322;.NET CLR 2.0.50727;.NET CLR 3.0.04506.30))
Exception: System.Web.HttpException
Message: A public action method 'ResetPassword' could not be found on controller 'MyApp.Controllers.UserController'.
Here's the HTML as it is rendered to the browser.
<form action="/User.mvc/ResetPassword" class="standard-form small-form" method="post">
<fieldset>
<div class="row">
<label for="usernameTextBox">User Name</label>
<input type="text" name="username" id="usernameTextBox" />
</div>
<div class="row">
<label for="emailTextBox">Email Address</label>
<input type="text" name="email" id="emailTextBox" />
</div>
<div class="row">
<label> </label>
<input type="submit" value="Reset Password" />
</div>
</fieldset>
</form>
And here's the signature of my ResetPassword action.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ResetPassword(string username, string email)
(and yes, the email address is required to match the one we have on file)

Possibly an answer raising more questions than actual answers, but in the spirit of trying to help...
On the GET calls, are "username" and "email" querystring parameters actually supplied? (your IIS log file may be recording query strings, so check there). If so, then the answer of Ben S may well apply.
If your web site is internet facing, then these calls may just be spiders not playing nicely.
If your site is internal, I'd suspect a user is playing with "refresh".
Have you tracked the client IP addresses which raise these errors?

I don't think you can do anything about this. Some browser plug-ins/toolbars have a feature which allows changing forms from GET -> POST and vice-versa.
If your users are doing this, there isn't really anything you can do.

When website visitors misbehave like this, you have to ask yourself, "What are the chances this is a legitimate misunderstanding?" In my opinion, using the wrong HTTP method is not something a browser does because it's old or buggy or whatever. It's an invalid request, so send 'em a 405 and be done with it.
(I have heard of some browsers and plugins trying to 'preload' pages that are reachable from the current page, but it's a lame 'feature'. My answer is still to treat it as an invalid request.)

I'd say it isn't really your problem. You design your site to work as intended, you put your GET/POST restrictions on your methods (for security or other reasons).
If the user tries to get around your security with some advanced tools/plugins (such as GET/POST switches) it's not your concern. You might want, however, to add some custom error pages to handle those scenarios and warn the user accordingly.

Related

Is ASP.NET MVC's Checkbox Implementation Accessible / Screen Reader-Friendly?

If you've ever looked at what ASP.NET MVC actually renders when you use #Html.CheckBoxFor, then you've seen that each checkbox you request to be rendered actually results in the emission of not one but two input tags. One is the "true" value checkbox, and the other is for "false." The latter input is of type "hidden".
Generally this doesn't cause problems if you're using ASP.NET MVC correctly. You wouldn't notice the input doubling unless you tried to, for example, do something directly with Request.Form(e.g. Why does ASP.NET MVC Html.CheckBox output two INPUTs with the same name?)
My question, though, is how screen readers deal with this. For example, can they be relied upon to correctly report only the visible checkbox to the site user?
Screen readers will ignore hidden inputs.
Given the example you cite in your comment, it returns this code:
<div class="col pure-u-xl-1-3 pure-u-lg-1-3 pure-u-md-1 pure-u-sm-1 pure-u-xs-1">
<label>Home Club Newsletter</label>
<input checked="checked" … id="newsletter" name="JoinHomeClub" type="checkbox" value="true">
<input name="JoinHomeClub" type="hidden" value="false">
<span class="checkbox-label">Yes, please sign me Up!</span>
</div>
Right off the bat there is a problem here because the <label> is not associated with the control, and the visible text that is next to the checkbox is not associated with the field.
When I access the field in NVDA, all it says is "checkbox checked". There is no accessible name at all.
But to your question…
Your question was related to the <input type="hidden">. As #SLaks said, screen readers ignore <input type="hidden">. The fact that they have the same name value is no problem. If they had the same id value, then you would have a problem (how it would manifest in a screen reader depends on things and stuff).

Sending long text from web form to server

I try to move my text analyzer from console to web form.
I have simple form like this:
<form action="/">
<textarea name="str"></textarea>
<input type="submit">
</form>
Generally I could have very long texts for analysis inside of textarea. When I submit the form I get the following from thin:
Invalid request: Header longer than allowed
So the question is what is the proper approach to send long texts to server? Uploading files or filling links to url are not the option unfortunately.
By default the method of a form is GET, which has a limit on the number of characters allowed. (The limit depends on server and client, see for instance this answer, which specifies that usually it is 8KB).
You should use instead a method POST, which has much larger limit, around 2GB.
<form action="/" method="POST">
<textarea name="str"></textarea>
<input type="submit">
</form>

How rewrite URL?

I'm making a single web app.
I have a form with a POST method and an action value equal to "/login".
<form action="/login" method="POST">
<label for="mail">Email</label><input name="log" id="mail" type="text">
<label for="pass">Pass</label><input name="pass" id="pass" type="text">
<input type="submit">
When the submit button is press, server get the form, then return to the index page.
But, in the address bar, I have "local:5050/login" and would have "local:5050".
Can I remove the "login" mention ?
Since you are making a SPA, you will not want to have the POST method of the form actually complete. Generally this is done in dart by attaching a listener on the form element, within that listener you would then do a couple of things:
1) Cancel the default action (Also see: How do I prevent an on.submit event from changing/reloading the page?)
2) Get the values you're interested in from the form (or potentially take the entire form itself)
3) Send the values via an AJAX request to the server and listen for the response from the server to verify it was valid etc.
See the Dart tutorials on forms for more information on accomplishing the other steps.

Clarifying POST-ing to a site

Say I were to post to a site using www.mysite.com?user=myuser does that simulate the submit button that is associated with that form? If so, what happens if there are a number of submit buttons in the form?
Also, if that button's html is like so <input name="button" class="button" type="button" value="Save" onclick="javascript: submit()" disabled> with the "disabled" attribute, does that mean I can't POST www.mysite.com?user=myuser/won't work?
<form name="Form" method="post" action="/thisAction.do">
<input type="text" name="inquiryNo" maxlength="11" value="" onkeyup="javascript: checkNo()">
<input name="buttonInquire" class="button" value="Inquire" onclick="javascript: submitInquire()" type="button">
<!--Then comes a number of other inputs-->
<input.../>
<input.../>
<input.../>
<input name="modify" class="button" type="button" value="Save"
onclick="javascript: submitModify()" disabled>
</form>
This is some sample code as it's work stuff which I am not allowed to share. So when I use the inquire action a new account successfully loads up and the details are presented on the page. The modify action is meant to 'modify' those details but it just returns the same details displayed on the page. I get no sort of feedback from anything.
You can POST to a URL with a query string (the stuff after the ?), and since you say you're using urllib2 with a data argument, that's what happens. The server can then read both the POST data and the query string and do whatever it wants, though most of the time they're merged together or the query string is ignored entirely.
disabled only stops you from clicking the button in the browser (and even then, you can just un-disable it with a tool like Firebug). You can POST whatever you want to any URL you want; HTML can't stop you, though the server can still give you an error if it wants.
I think your problem is that "inquire" is the default action, and something's wrong with your POST. So no matter what you send, the server isn't recognizing it and is falling back to "inquire".
It looks like the form is intended to send modify=Save. Can you post the Python code you're actually running?
No, what you actually typed in is a GET method.
There are 2 ways of submitting data: POST AND GET.
Post is by submitting data by using a form in a webpage that posts to another on the background, while GET is setting the data in the url itself like user=myuser.
Most of the times using a GET method (url query string) will not work if the web programmer actually is checking for a POST method. The same happens if the programmer is waiting for a GET request and you actually POST it.
However there is a php var called REQUEST which will work with GET and POST.
I'm no professional in PHP but because you had no answers at the moment I tried my best to explain it. Hopefully some expert will come along and explain it properly.
You edited your question while I was replying so you need someone to answer you on your second question.

quiet bot detection and filtering in ASP.NET MVC

I'm setting up an e-mail form and I need to be able to check for bots and filter them quietly. The site runs ASP.NET MVC. I'd like to avoid CAPTCHA. Any ideas?
Add a new input field, label it "Please leave blank", hide it using CSS, and ignore the post if that field is filled in. Something like this:
<style type='text/css'>
#other_email_label, #other_email {
display: none;
}
</style>
...
<form action='mail'>
<label id='other_email_label' for='other_email'>Please leave blank:</label>
<input type='text' name='other_email' id='other_email'>
...
</form>
So a human being won't see that field (unless they have CSS turned off, in which case they'll see the label and leave it blank) but a spam robot will fill it in. Any post with that field populated must be from a spam robot.
(Copied from my answer to this related question: "What is a good invisible captcha?")
IIRF can do blacklisting based on user-agent or IP address (or other things).
Works with ASP.NET, PHP, anything. Runs on IIS5, 6, 7. Fast, easy, free.
You can browse the doc here.
I saw a solution to this with forms, the premise was using JavaScript to count keystrokes and time the distance from page_load to form submission. It then guessed if it was a bot based on that time and a typical expectation boundary for keystrokes/second as bots (that use the browser) tend to dump text very quickly without strokes (just a ctrl-v).
Bots just sending POST or GET data without loading the page just get filtered too.
I don't know the details of the implementation, but might be an idea.

Resources