{"record":{"id":"a0e66f910180fde6","repo":"nopSolutions/nopCommerce","slug":"request-data-is-missing","errorCode":null,"errorMessage":"Request data is missing","messagePattern":"Request data is missing","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"error","filePath":"src/Plugins/Nop.Plugin.ExternalAuth.Facebook/Controllers/FacebookDataDeletionController.cs","lineNumber":70,"sourceCode":"        str = str.Replace(\"-\", \"+\").Replace(\"_\", \"/\");\n        var paddingToAdd = (str.Length % 4) == 3 ? 1 : (str.Length % 4);\n        var charToAdd = new string('=', paddingToAdd);\n\n        return str += charToAdd;\n    }\n\n    #endregion\n\n    #region Methods\n\n    [HttpPost]\n    public async Task<IActionResult> DataDeletionCallback(IFormCollection form)\n    {\n        try\n        {\n            string signed_request = form[\"signed_request\"];\n            if (string.IsNullOrEmpty(signed_request))\n                throw new NopException(\"Request data is missing\");\n\n            var split = signed_request.Split('.');\n            var signatureRaw = DecodeUrlBase64(split[0]);\n            var dataRaw = DecodeUrlBase64(split[1]);\n            if (string.IsNullOrEmpty(signatureRaw) || string.IsNullOrEmpty(dataRaw))\n                throw new NopException(\"Part of the request data is missing\");\n\n            var signature = Convert.FromBase64String(signatureRaw);\n            var dataBuffer = Convert.FromBase64String(dataRaw);\n            var json = Encoding.UTF8.GetString(dataBuffer);\n            var appSecretBytes = Encoding.UTF8.GetBytes(_facebookExternalAuthSettings.ClientSecret);\n            HMAC hmac = new HMACSHA256(appSecretBytes);\n            var expectedHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(split[1]));\n            if (!expectedHash.SequenceEqual(signature))\n                throw new NopException(\"Hash validation failed\");\n\n            var fbUser = JsonConvert.DeserializeObject<FacebookUserDTO>(json);\n            var authenticationParameters = new ExternalAuthenticationParameters","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Plugins/Nop.Plugin.ExternalAuth.Facebook/Controllers/FacebookDataDeletionController.cs#L52-L88","documentation":"Thrown by FacebookDataDeletionController.DataDeletionCallback as a NopException when form['signed_request'] is null or empty. Facebook sends a signed_request in the form body of data-deletion callbacks; its absence means the request is malformed or not a genuine Facebook callback.","triggerScenarios":"A POST to the data-deletion callback endpoint with no 'signed_request' field — e.g. a probe, a misconfigured webhook, a manual test without the field, or Facebook retrying a malformed payload.","commonSituations":"Someone hits the endpoint directly; webhook URL registered with Facebook is wrong and Facebook posts a different payload shape; a proxy/load balancer strips form fields.","solutions":["Confirm the data-deletion callback URL registered in the Facebook app exactly matches this endpoint.","Ensure the request reaches the controller with the multipart/form-data body intact (check reverse proxies).","For testing, POST a real signed_request generated with your app secret."],"exampleFix":"// before: curl -X POST https://shop/Facebook/DataDeletionCallback   (no body)\n// after: include signed_request\n//   curl -X POST https://shop/Facebook/DataDeletionCallback \\\n//        -d 'signed_request=<payload>.<signature>'","handlingStrategy":"validation","validationCode":"string signed = form[\"signed_request\"];\nif (string.IsNullOrEmpty(signed))\n    return BadRequest(\"signed_request is required.\");","typeGuard":"static bool HasSignedRequest(IFormCollection form) =>\n    !string.IsNullOrEmpty(form[\"signed_request\"]);","tryCatchPattern":"try { return await DataDeletionCallback(form); }\ncatch (NopException ex) when (ex.Message.Contains(\"Request data is missing\"))\n{ return BadRequest(ex.Message); }","preventionTips":["Register the exact data-deletion callback URL in the Facebook app.","Ensure proxies forward the form body unchanged.","Return 400 for missing fields instead of bubbling the exception."],"tags":["external-auth","plugins","facebook","webhook","validation","security"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}