BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

19
BIT 286: Web Applications Lecture 10: Thursday, February 5, 2015 ASP.Net Form Submission

Transcript of BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

Page 1: BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

BIT 286: Web Applications

Lecture 10: Thursday, February 5, 2015

ASP.Net Form Submission

Page 3: BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

3

Examining Edit:First Visit:Controller

Controller method for first time (non-POST) visit:

Notice how similar this looks to the Details page

// GET: Movies/Edit/5

public ActionResult Edit(int? id)

{

if (id == null)

{

return new HttpStatusCodeResult(HttpStatusCode.BadRequest);

}

Movie movie = db.Movies.Find(id);

if (movie == null)

{

return HttpNotFound();

}

return View(movie);

}

Page 4: BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

4

Examining Edit:First Visit:the View

Edit.cshtml

@model MVCBasics.Models.Movie

@{ ViewBag.Title = "Edit"; }

<h2>Edit</h2>

@using (Html.BeginForm())

{

@Html.AntiForgeryToken()

<div class="form-horizontal">

<h4>Movie</h4>

<hr />

The rendered HTML

<h2>Edit</h2>

<form action="/Movies/Edit/1" method="post">

<input name="__RequestVerificationToken" type="hidden" value="iYr5boxkobMxM-9Ad4T9zZ_AcVmdy7Pv6k5Z_mhyIbSgN3P6uv3G8oheeQ2u_IrBLmdyYyXbMRs5ECU4wrE_g5s70fRyQP5pKg4TRC1p_mE1" />

<div class="form-horizontal">

<h4>Movie</h4>

Page 5: BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

5

XSRF/CSRFCross-Site Request Forgery Good explanation at ASP.Net

Essentially, you visit Web Site #1 and legitimately log in

The browser keeps the authentication info until the web browser process exits

The browser also automatically re-sends the authentication info whenever you visit that site.

This is very convenient when you’re on Web Site #1

You go to Web Site #2, which attempts to access Web Site #1

E.g., Web Site #2 creates it’s own form, whose action is to submit to Web Site #1

Your browser conveniently re-sends the authentication info along with the form

Web Site #2 can now act as you on Web Site #1

This is the ‘cross site’ part

I’ve heard that this can be done even by ads served to you on pages you trust.

I’d be surprised if Google, MS, etc, would let this happen, but you don’t control which ad-serving arrangements are used by the websites you visit.

Page 6: BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

6 XSRF/CSRFCross-Site Request Forgery

We can combat this with anti-forgery tokens

Web Site #1 will generate a random number and put it into a hidden field in the form it sends to you

(This is the anti-forgery token)

Web Site #1 will check (when you post that form back) that the number in your form matches the one it sent you

This prevents Web Site #2 from making up it’s own form

Because it can’t generate the same random numbers as Web Site #1

Page 7: BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

7

Examining Edit:First Visit:the View

Edit.cshtml

<div class="form-horizontal">

<h4>Movie</h4>

<hr />

@Html.ValidationSummary(true, "", new { @class = "text-danger" })

@Html.HiddenFor(model => model.ID)

<div class="form-group">

@Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })

<div class="col-md-10">

@Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })

@Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })

</div>

</div>

<div class="form-group">

<div class="col-md-offset-2 col-md-10">

<input type="submit" value="Save" class="btn btn-default" />

</div>

</div>

</div>

}

<div>

@Html.ActionLink("Back to List", "Index")

</div>

@section Scripts {

@Scripts.Render("~/bundles/jqueryval")

}

The rendered HTML

<input data-val="true" data-val-number="The field ID must be a number." data-val-required="The ID field is required." id="ID" name="ID" type="hidden" value="1" />

<div class="form-group">

<label class="control-label col-md-2" for="Title">Title</label>

<div class="col-md-10">

<input class="form-control text-box single-line" id="Title" name="Title" type="text" value="Movie Title #1" />

<span class="field-validation-valid text-danger" data-valmsg-for="Title" data-valmsg-replace="true"></span>

</div>

</div>

Page 8: BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

8

Examining Edit:POSTing the edits:Controller

Controller method for POST visit:

[HttpPost] // Only used for HTTP POST requests; HTTP Get is the default

[ValidateAntiForgeryToken] // checks @Html.AntiForgeryToken() from View

public ActionResult Edit([Bind(Include = "ID,Title,ReleaseDate,Genre,Price")] Movie movie)

{

if (ModelState.IsValid)

{

db.Entry(movie).State = EntityState.Modified;

db.SaveChanges();

return RedirectToAction("Index");

}

return View(movie);

}

Page 9: BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

9 Examining Edit:POSTing the edits

Controller method for POST visit:

public ActionResult Edit( [Bind(Include =

"ID,Title,ReleaseDate,Genre,Price")] Movie movie)

{ /* Snip */ Include is the list of properties (data fields) to extract from the form

Other fields are left blank in the movie object, even if they’re present in the form

These data fields are filled in for you, automatically, on the movie object.

Page 10: BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

10 Security Risk: Overposting

Normally you’d never put extra properties in your form….

…but hackers might download & save a copy and add stuff.

For example, let’s say that the ‘Edit User’s Unimportant Account Info’ page normally just lets you update your firstname, last name, nickname, picture, etc, etc.

But does NOT let you change the password

You can go to that page, select ‘Save As’ in your browser, edit the form locally to also include a new password for the user, and then submit the form.

If you blindly bound the movie object to ALL fields, and saved the whole object you’d update the password

The ‘Include’ attribute allows you to only bind to some of the fields

Also a good explanation at MSDN

Page 12: BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

12 Tutorial Outline Adding a search term

‘Search’ Param added to controller method

LINQ query

Important details about when this actually gets executed

Goofy re-use of ‘id’ parameter for a nicer URL

Adding a form

Want to use GET, not POST (GET = retrieve, POST = change DB state)

Decorate form so that it’ll get, not post

Filtering by genre

Querying for the list of genres

Handling a GET’d search

Updating the view to support the above

Page 13: BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

13

Adding a parameter

public ActionResult Index(string searchString)

{

var movies = from m in db.Movies

select m;

if (!String.IsNullOrEmpty(searchString))

{

movies = movies.Where(s => s.Title.Contains(searchString));

}

return View(movies);

}

This is LINQ This defines, but does NOT execute the query

This modifies the definition of the queryLINQ actually maps to SQL (as opposed to doing a SELECT * and then filtering the results in C#

Page 14: BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

14 My opinion: using ‘id’ as the parameter

This seems goofy – it does produce a nice URL, but the controller code is kinda ugly (notice how they promptly renamed the parameter)

Page 16: BIT 286: Web Applications Lecture 10 : Thursday, February 5, 2015 ASP.Net Form Submission.

16 Outline