Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/Core/Resolvers/MsSqlQueryExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ public override string GetSessionParamsQuery(HttpContext? httpContext, IDictiona

// Counter to generate different param name for each of the sessionParam.
IncrementingInteger counter = new();
const string SESSION_KEY_NAME = $"{BaseQueryStructure.PARAM_NAME_PREFIX}session_key";
const string SESSION_PARAM_NAME = $"{BaseQueryStructure.PARAM_NAME_PREFIX}session_param";
StringBuilder sessionMapQuery = new();

Expand All @@ -528,10 +529,12 @@ public override string GetSessionParamsQuery(HttpContext? httpContext, IDictiona

foreach ((string claimType, string claimValue) in sessionParams)
{
string keyName = $"{SESSION_KEY_NAME}{counter.Current()}";
string paramName = $"{SESSION_PARAM_NAME}{counter.Next()}";
parameters.Add(keyName, new(claimType));
parameters.Add(paramName, new(claimValue));
// Append statement to set read only param value - can be set only once for a connection.
Comment thread
RubenCerna2079 marked this conversation as resolved.
string statementToSetReadOnlyParam = "EXEC sp_set_session_context " + $"'{claimType}', " + paramName + ", @read_only = 0;";
string statementToSetReadOnlyParam = "EXEC sp_set_session_context " + keyName + ", " + paramName + ", @read_only = 0;";
sessionMapQuery = sessionMapQuery.Append(statementToSetReadOnlyParam);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
// Licensed under the MIT License.

#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
using Azure.DataApiBuilder.Config.ObjectModel;
Expand Down Expand Up @@ -325,7 +327,6 @@ public async Task TestValidStaticWebAppsEasyAuthTokenWithAnonymousRoleOnly()
DisplayName = "Anonymous role - X-MS-API-ROLE is not honored")]
[DataRow(true, "author",
DisplayName = "Authenticated role - existing X-MS-API-ROLE is honored")]
[TestMethod]
public async Task TestClientRoleHeaderPresence(bool addAuthenticated, string clientRoleHeader)
{
string generatedToken = AuthTestHelper.CreateStaticWebAppsEasyAuthToken(addAuthenticated);
Expand All @@ -344,6 +345,46 @@ await SendRequestAndGetHttpContextState(
ignoreCase: true);
}

/// <summary>
/// Tests we ensure that an invalid query in the EasyAuth header does not result in a successful request.
/// </summary>
[TestMethod]
public async Task TestInvalidQueryInHeader()
{
string header = @"
{
""auth_typ"":""aad"",
""claims"":[
{
""typ"":""x', N'v';SET IDENTITY_INSERT authors ON;INSERT INTO authors (id, name, birthdate) VALUES (10001, 'Hidden Author', '2001-01-01');SET IDENTITY_INSERT authors OFF;SELECT 1 AS inserted FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;--"",
""val"":""x""
}
],
""UserRoles"":[""anonymous""]
}";

string generatedToken = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(header));
HttpContext postMiddlewareContext =
await SendRequestAndGetHttpContextState(
generatedToken,
EasyAuthType.StaticWebApps,
clientRoleHeader: "anonymous");
Comment thread
RubenCerna2079 marked this conversation as resolved.
Outdated
Assert.AreEqual(expected: (int)HttpStatusCode.OK, actual: postMiddlewareContext.Response.StatusCode);

using IHost host = await WebHostBuilderHelper.CreateWebHost(EasyAuthType.StaticWebApps.ToString(), false);
TestServer server = host.GetTestServer();
HttpClient client = server.CreateClient();

HttpRequestMessage request = new(HttpMethod.Get, $"api/Author/id/10001");
HttpResponseMessage response = await client.SendAsync(request);
string responseBody = await response.Content.ReadAsStringAsync();
Comment thread
RubenCerna2079 marked this conversation as resolved.
Outdated

Assert.IsFalse(responseBody.Contains($"\"id\":10001"),
"The GET request should not return the invalid row.");
Assert.IsFalse(responseBody.Contains("Hidden Author"),
"The GET request should not return any information related to the invalid row.");
}

/// <summary>
/// - Ensures an invalid EasyAuth header payload results in HTTP 401 Unauthorized response
/// A correctly configured EasyAuth environment guarantees an EasyAuth payload for authenticated requests.
Expand Down
Loading