1
votes

I am working on a project that uses both MVC and KnockoutJS and I am wondering about how best to provide security to the site.

Here is my issue.

I am allowing views to be created using Razor and I am using Knockout to power a lot of the features via JQuery dialogs. I have a master view model that looks as follows:

my.MasterViewModel = function () {
    var
    CatalogsViewModel = ko.observable(null)
    BulkUploadViewModel = ko.observable(null),
    ExploitationTypeViewModel = ko.observable(null),
    ExploitationViewModel = ko.observable(null),
    InviteSongWriterViewModel = ko.observable(null),
    ManageCollaboratorsViewModel = ko.observable(null),
    ManageSongwriterViewModel = ko.observable(null),
    ManageSongViewModel = ko.observable(null),
    ProViewModel = ko.observable(null),
    SongsViewModel = ko.observable(null),
    TagsViewModel = ko.observable(null),
    TweaksViewModel = ko.observable(null),
    NotificationsViewModel = ko.observable(new my.notificationsviewmodel());

    return {
        CatalogsViewModel: CatalogsViewModel,
        BulkUploadViewModel: BulkUploadViewModel,
        ExploitationTypeViewModel: ExploitationTypeViewModel,
        ExploitationViewModel: ExploitationViewModel,
        InviteSongWriterViewModel: InviteSongWriterViewModel,
        ManageCollaboratorsViewModel: ManageCollaboratorsViewModel,
        ManageSongwriterViewModel: ManageSongwriterViewModel,
        ManageSongViewModel: ManageSongViewModel,
        ProViewModel: ProViewModel,
        SongsViewModel: SongsViewModel,
        TagsViewModel: TagsViewModel,
        TweaksViewModel: TweaksViewModel,
        NotificationsViewModel: NotificationsViewModel
    };
}();

In my click handlers I then instantiate the required view models and all is well, this works great!

The issue that I'm having is that I have things as follows in my Razor syntax:

<li><a href="#" data-songid="@Model.Song.Id" class="icon-margin-left manage-song">Edit Song</a></li>

In my click handler I read the data-songid value and load the data from the server using knockout. This also works great, however, it is not exactly hard to change the data-songid value in chrome, or firebug, or any number of development tools. Once that value is changed the user can then click the link and edit a different entity... :S

Is there a better way for me to do this? I am very concerned that this is a HUGE security hole in my application.

Thanks in advance!

2

2 Answers

3
votes

Assuming that you have applied Asp.Net authentication on your website then the Ajax request from Knockout should contain the Asp.Net authentication cookie (unless the request is cross domain) so you can apply server side authentication/authorization before returning the data. As Alex points out, this is essential and the only way to be sure your user can only modify their own data.

As you say though, this doesn't prevent the user from changing the ID but it does prevent them from modifying data that they are not allowed to modify. Often I think this is sufficient, as your user can only modify their own data which presumably they can edit anyway?

If you really need to be sure that the user hasn't changed the value then you can salt the ID and generate a server side digest before outputting it in the Razor page. This can then be used to verify that the value hasn't been modified when it is sent back in the Ajax request. This post gives an example of using this technique for tamper proofing URL query strings but can be easily adapted to a scenario like yours: http://www.pradyblog.com/index.php/2012/08/20/creating-tamper-proof-url-in-asp-net-a-way-to-prevent-spoofing-and-forged-http-requests/

1
votes

A better way is to check permissions on a server side.

You are right that it's easy to tweak JS variables in browser development tools. It's also easy to forge entire HTTP request sent to server.

The rule is to never trust user's input and always verify that this particular user has permissions to edit this particular song when handling request in a back-end.