-
Frank Lange authoredFrank Lange authored
Security considerations
SPARQL injection
A common use case of (web) application backends is to process user inputs and transport them to the database layer by means of executing queries in the specific database query language (e.g. SPARQL or SQL). A typical pattern is to inject values into the database query via string manipulation. Insufficient validation/sanitization of the user input to be injected enables an attack vector called injection attack where the attacker is able to execute malicious statements of the database query language inside the query.
Literature
General:
- SPARQL/RDQL/SPARUL Injection: slides and website
- W3C:
- Towards Secure SPARQL Queries in Semantic Web Applications using PHP (Extended Version)
Mitigation in semantic web frameworks:
- Apache Jena:
- dotNetRDF: SparqlParameterizedString
- RDFLib: Prepared Queries
Escaping:
Malicious federated queries
Once a SPARQL injection attack is successful one particularly interesting attack scenario is the execution of federated queries (aka SERVICE
). These could aim to query another RDF dataset that is exposed by the same triplestore via a SPARQL endpoint (e.g. for information disclosure).
Another interesting "application" of federated queries is to target HTTP endpoints inside the infrastructure of the triplestore such as those of Fuseki's HTTP Administration Protocol. This kind of attack type is a Server Side Request Forgery. By default, Apache Jena's SPARQL engine uses either GET or POST to query a remote SPARQL endpoint to execute a federated query depending on the size of the query inside the SERVICE
statement (size limit is 2048 bytes according to the documentation). For instance the SPARQL query
SELECT * WHERE {
SERVICE <http://127.0.0.1:3030/$/backup/dalia> {
?s ?p "<a very long string>"
}
}
can trigger the backup endpoint with POST, thus initiating a backup of the dalia dataset.
Note: This kind of attack vector has been disabled by setting arq:httpServiceSendMode
to "asGetAlways"
with commit bb535029.
Parameter injection into SPARQL queries in this project
RDFLib's prepared queries cannot be used because they are not supported by SPARQLStore
.
Our business logic uses a query builder to construct SPARQL queries. User input can be injected via a Literal
(strings, numbers, etc.) or URIRef
(URIs) object. Upon serialization of the QueryBuilder
object to a string via its build()
method the n3()
method is called for all nested objects to give their string representation in Notation3 format.
Strings
Literal
's n3()
method returns a quoted string with proper escaping of problematic characters, which happens in the _quote_encode
method. This seems to be a safe way to inject strings and has been pentested extensively by the developer of this project.
URIs
URIRef
's n3()
method tests for invalid characters in the URI and raises an exception upon detection.