Ensuring the safety of JavaScript requests made to a Web Service

In my project, there is a page that triggers a JSon script when a button is clicked. This script interacts with a web service. To ensure security, the code behind the page generates a script containing an object with a unique code. This code is then added to the header of the page. However, the web service fails to verify this code as it cannot find the specified header (in other words, the header does not exist).

The following code snippet generates the code and JavaScript object (in .cs file):

    string cacheKey = User.Identity.Name + ":securityTicket";
    string securityTicket = Guid.NewGuid().ToString();

    Cache[cacheKey] = securityTicket;

    string script = string.Format("SECURITY_TICKET = '{0}';", securityTicket);

    ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "securityKey", script, true);

This script adds the header (in .aspx file)

    function onInvoke(sender, args) {
        args.get_webRequest().get_headers()['securityTicket'] = SECURITY_TICKET;);
    }

The backend code for the web service (asmx.cs or similar): HttpContext context = HttpContext.Current;

        string headerTicket = context.Request.Headers["securityTicket"];

        if (string.IsNullOrEmpty(headerTicket))
        {
            throw new SecurityException("Security ticket must be present.");
        }

        string cacheKey = context.User.Identity.Name + ":securityTicket";
        string cacheTicket = (string)context.Cache[cacheKey];

        if (string.Compare(headerTicket, cacheTicket, false) != 0)
        {
            throw new SecurityException("Security ticket mismatched.");
        }

The issue arises when context.Request.Headers["securityTicket"] returns null.

Any insights or suggestions would be greatly appreciated. Thank you!

UPDATE:

The Web service:

namespace PV
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ScriptService()]
    public class UserService : System.Web.Services.WebService
    {
        [WebMethod]
        public bool ChangeUserPassword(object userID, object password)
        {
            EnsureTicket();
            return PV.WebMethods.ChangeUserPassword(userID, password);
        }

        private void EnsureTicket()
        {
            HttpContext context = HttpContext.Current;

            string headerTicket = context.Request.Headers["securityTicket"];

            if (string.IsNullOrEmpty(headerTicket))
            {
                throw new SecurityException("Security ticket must be present.");
            }

            string cacheKey = context.User.Identity.Name + ":securityTicket";
            string cacheTicket = (string)context.Cache[cacheKey];

            if (string.Compare(headerTicket, cacheTicket, false) != 0)
            {
                throw new SecurityException("Security ticket mismatched.");
            }
        }
    }
}

The Page:

    <script type="text/javascript" language="javascript">
    var prm = Sys.WebForms.PageRequestManager.getInstance();
    prm.add_beginRequest(beginRequest);
    function beginRequest(sender, args) {
        prm._scrollPosition = null;
        postbackElement = args.get_postBackElement();
    }
    var postbackElement;
    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequest);
    Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoaded);

    function pageLoaded() {
        Sys.Net.WebRequestManager.add_invokingRequest(onInvoke);
        if (typeof (postbackElement) === "undefined") {
            return;
        }
        if ((postbackElement.id).indexOf("btnSelect") !== -1) {
            $("html, body").animate({ scrollTop: "300px" });
        }
    }

    function ApplicationLoadHandler() {
        // InitScript is a custom function 
        // registered from the User Control
        if (typeof InitScript == 'function')
            InitScript();
    }

    if (Sys && Sys.Application) {
        Sys.Application.add_load(ApplicationLoadHandler);
        Sys.Application.notifyScriptLoaded();
    }

    function pageUnload() {
        Sys.Net.WebRequestManager.remove_invokingRequest(onInvoke);
    }

    function onInvoke(sender, args) {
        args.get_webRequest().get_headers()['securityTicket'] = SECURITY_TICKET;
        alert('Security ticket: ' + args.get_webRequest().get_headers()['securityTicket']);
    }
</script>

    <%
    Response.Write(@"
        <script>
        function ResetPassword() 
        {
            var password = document.getElementById(""password"").value;
            var id = document.getElementById(""ctl00_ctl00_ContentPlaceHolder1_cphContent_hdnUsrID"").value;
            var d = {""userID"" : id, ""password"" : password };
            $.ajax
            ({
                type: ""POST"",
                url: """ + "" + @"http://localhost:2297/wwwroot/Services/UserService.asmx/ChangeUserPassword"",
                data: JSON.stringify(d),
                contentType: ""application/json"",
                dataType: ""json"",
                success: function() 
                {
                    document.getElementById(""password"").value = '';
                    alert('Success');
                    $(""" + "#ctl00_ctl00_ContentPlaceHolder1_cphContent_pnlChangePassword" + @""").fadeOut();
                    $(""html, body"").animate
                    (   {
                            scrollTop: $(""" + "#ctl00_ctl00_ContentPlaceHolder1_cphContent_pnlPerson" + @""").offset().top - 100
                        }, 1200);
                },
                error: function(msg) 
                {
                    if(msg === false) 
                    {
                        alert('Error');
                        return;
                    }
                }
            })
        }

        function passwordChanged_Success() { 
            alert('Changed');
        }

        function passwordChanged_Failed() { 
            alert('Failed');
        }
        </script>"); %>

The page includes an update panel.

The page's code behind:

private void GenerateSecurityTicket()
{
    string cacheKey = User.Identity.Name + ":securityTicket";
    string securityTicket = Guid.NewGuid().ToString();

    Cache[cacheKey] = securityTicket;

    string script = string.Format("SECURITY_TICKET = '{0}';", securityTicket);

    ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "securityKey", script, true);
}

protected void Page_Load(object sender, EventArgs e)
{
    this.GenerateSecurityTicket();
}

Answer №1

Here is how my files are structured:

Students.aspx

<asp:ScriptManager ID="ScriptManager1" runat="server">
    <Services>
        <asp:ServiceReference Path="~/UserService.asmx" />
    </Services>
</asp:ScriptManager>
<script type="text/javascript" language="javascript">
    // JavaScript code here
</script>

UserService.asmx

<%@ WebService Language="C#" CodeBehind="~/App_Code/UserService.cs" Class="UserService" %>

UserService.cs

// C# code for UserService

Everything seems to be in place and should work fine. Let me know if there are any issues!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using HTML or JavaScript to generate a multitude of identical HTML elements on a webpage

I am currently designing a page that requires the presence of numerous tree illustrations with leaves, spanning across the width at the bottom of the page. I have considered two methods to achieve this. One option is to create a single set of trees and lea ...

Fill out a dropdown menu by selecting options from another dropdown menu

I'm currently working on populating a dropdown list based on the selection of another dropdown list. Here's what I have so far: Below is the function that takes the selected value from the first dropdown list as a parameter: [AcceptVerbs(HttpVe ...

Accessing a local JSON file in a ReactJS application without the need for a local server installation

I am encountering an issue with the file structure of src/resource/file.json. 1. Utilizing load-json and require to handle the file: class App extends Component{ constructor(props) { super(props); this.state = {summar ...

Syntax highlighting in custom blocks with VueJS

Vue single file components allow for the creation of custom blocks (besides the commonly used script, template, and style). For more information, you can refer to the official documentation here: . However, I am struggling to enable syntax highlighting w ...

Encountered an error while attempting to load resource: the server returned a 404 (Not Found) status code when trying to load an image in an

I am looking to dynamically load an image when it is selected from a file picker dialog. The code provided below attempts to achieve this, however, the image does not load into the img tag. <script src="https://cdnjs.cloudflare.com/ajax/libs/jq ...

Automatically activate the next tab in Bootstrap

I have a modal that performs a count. Once the count is completed, the modal closes. My goal is to automatically switch to the next tab in Bootstrap when the modal closes. Here is the HTML: <ul class="nav nav-tabs namelocationtable"> <div clas ...

Choosing between exclusive choices across multiple selection elements in Vue 3

In my Vue component, there are 5 distinct values stored in the options variable. I want users to select only one value from each of the 5 select options I provide. This means that once a user selects a value in one input select component, that same value c ...

Error Alert: React Native object cannot be used as a React child within JSON, leading to an Invariant Violation

When using React-Native: To start, here is the example code of a json file: Any placeholders marked with "..." are for string values that are not relevant to the question. [ { "id": "question1" "label": "..." "option": [ { "order": 1, "name": "..."}, ...

ProgressMeterJS Plugin - Full-width Progress Bar

I have encountered a question regarding this particular plugin found at: My goal is to adjust the progress bar's width to 100% so it matches the width of its container. So far, I have made modifications to the plugin by changing the following line: ...

Instructions for utilizing lodash or JavaScript to apply a filter to an object

Received this object from the Server: var data = { test1: { documents: [] }, test2: { documents: [{ vId: 'sdfas23', TypeId: '81', isDeleted: false }], answer: true }, test3: { documents: ...

Adding specific props, such as fullWidth, at a certain width, like 'sm', in Material UI React

My goal is to include the fullWidth prop when the screen reaches a size of 600px or greater, which is equivalent to the breakpoint sm. I attempted to implement the following code, but unfortunately, it does not seem to be functioning as intended. [theme ...

How can I stop full-page auto-scroll screenshot extensions from automatically scrolling?

As the owner of a membership website, I'm faced with the challenge of preventing users from easily taking full page screenshots of the valuable text content in my members area. Many browser extensions, such as Fireshot and GoFullPage, enable auto-scro ...

Encountering empty values during the process of decoding intricate JSON structures

My current project involves utilizing a 3rd party web API that provides a JSON string with specific formatting. The JSON string is enclosed in curly braces and contains various data points for GPS tracking: { "866968030210604":{ "dt_server":"201 ...

Creating a binary tree in vanilla JavaScript and styling it with HTML and CSS

I'm facing a challenge with my homework. I am required to convert my JavaScript binary tree into HTML and CSS, strictly using vanilla JavaScript without any HTML code. I have the tree structure and a recursive function that adds all the tree elements ...

"Implementing automated default values for Select/dropdown lists in ReactJs, with the added capability to manually revert back to the default selection

After browsing multiple websites, I couldn't find a clear solution on how to both set and select a default value in a select element. Most resources only explain how to set the value, without addressing how to reselect the default value. My Requireme ...

Using query strings to manipulate the URL of an iframe and add additional information

I am facing a challenge with integrating my legacy perl application into an MVC application. I have set up a structure where the legacy application is loaded into an iframe within default.aspx, but I need to capture the URL of each page within the iframe a ...

navigating to the start of a hyperlink

I'm having issues with scrolling to anchors and encountering 3 specific problems: If I hover over two panels and click a link to one of them, nothing happens. When I'm on section D and click on section C, it scrolls to the end of section C. ...

Retrieve content from HTML using PHP with unusual characters

Trying to retrieve data from the JSON API url: "". The data appears normal on the website, but when using HTML_GET_CONTENTS it displays strange characters: š[‹$G’…ÿŠÈçD¸›ßóqØ]æabѲƒüª.¦»JT—F¡ÿ¾ŸEFfFu÷ö@T™G„¹Ûåœc ...

Using multiple header tags in HTML

I have been tasked with developing a webpage featuring a prominent header at the top of the page. This header will include the navigation bar, logo, and website title. As the user begins to scroll, I want the header to transform into a compact version that ...

How can I resize several images to fit seamlessly within a div container?

Looking for a smart method to resize multiple images to fit neatly inside a fixed-size div? I've considered using JavaScript to calculate the div's width, dividing it by the number of images, and resizing them equally while maintaining their asp ...