Reputation: 82
My server works as a proxy for a user's search request. Before requesting data on Azure we need to ensure everything is secure. For this we add certain filters into the query filter. Let's say my server receives this query:
search=&$top=10&$filter=customer/customerId gt 1 and customer/customerId lt 5
I want to break it apart, investigate it's filter piece by piece and inject a security filter into it.
First thing I do is I get the filter:
var parsed = HttpUtility.ParseQueryString(query);
var filter = parsed["$filter"];
Next, I want to process it in order to verify and make changes.
After reading this post I am trying to utilize ODataUriParser
like so:
// 1. Create a dummy model
public static IEdmModel GetEdmModel()
{
var model = new EdmModel();
EdmEntityType customer = new EdmEntityType("Namespace", "Customer");
customer.AddKeys(customer.AddStructuralProperty("CustomerId", EdmPrimitiveTypeKind.Int32));
model.AddElement(customer);
return model;
}
// 2. Utilize it
static void Foo()
{
var query = "search=&$top=5001&$filter=Customer/CustomerId eq 1";
var parsed = HttpUtility.ParseQueryString(query);
var filter = parsed["$filter"];
var result = new ODataUriParser(HardCodedTestModel.TestModel, new Uri(filter, UriKind.Relative));
var parsedFilter = result.ParseFilter();
}
This throws an exception to me, saying:
Unhandled exception. Microsoft.OData.UriParser.ODataUnrecognizedPathException: Resource not found for the segment 'Customer
Upvotes: 0
Views: 499
Reputation: 8634
Your EDM model doesn't appear to include an entity set, so it's not clear what the filter is filtering. Azure Cognitive Search defines an EDM model for each index that includes an entity set "docs", the type of which corresponds to the index definition. The property path Customer/CustomerId
in the filter would be interpreted by Azure Cognitive Search as the CustomerId
sub-field of a top-level Edm.ComplexType
field named Customer
(Using OData terminology, the document is the entity, Customer
is a Complex property, and CustomerId
is a property of Customer
). Your EDM model will have to include all this schema information if you want to use ODataUriParser
or ODataQueryOptionParser
to obtain a semantic AST from the filter text.
That said, you probably don't need a full semantic AST to verify the security of the filter expression (assuming you're trying to defend against things like injection attacks). It might be simpler to use the lexical stage of the OData filter parser by itself. Then you can process the syntactic AST.
If you want maximum control, you can always roll your own parser. The full BNF for OData is here.
Upvotes: 1