Skip to content

Commit

Permalink
Add generic SPARQL escape helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
erikap committed Jun 6, 2017
1 parent 9deb85f commit 6d61845
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 13 deletions.
28 changes: 15 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,21 @@ Get the session id from the request headers.
#### sparql_client
Returns a SPARQL::Client instance connection to the SPARQL endpoint configured through the `MU_SPARQL_ENDPOINT` environment variable.

#### sparql_escape ; sparql_escape_{string|uri|date|datetime|bool|int|float}(value)
The Ruby templates extends the core classes `String`, `Date`, `DateTime`, `Time`, `Integer`, `Float`, `Boolean` and `URI` with a `sparql_escape` method. This method can be used to avoid SPARQL injection by escaping user input while constructing a SPARQL query. E.g.

```
query = " INSERT DATA {"
query += " GRAPH <#{settings.graph}> {"
query += " <#{user_uri}> a <#{RDF::Vocab::FOAF.Person}> ;"
query += " <#{RDF::Vocab::FOAF.name}> #{name.sparql_escape} ;"
query += " <#{RDF::Vocab::DC.created}> #{now.sparql_escape} ."
query += " }"
query += " }"
```

Next to the extensions, the template also provides a helper function per datatype that takes any value as parameter. E.g. `sparql_escape_uri("http://mu.semte.ch/application")`.

#### update(query)
Executes the given SPARQL update query.

Expand Down Expand Up @@ -115,16 +130,3 @@ You can now run your tests inside the container with:
## Experimental features
#### MU_SPARQL_UPDATE_ENDPOINT environment variable
Configure the SPARQL update endpoint path. This should be a path relative to the base of `MU_SPARQL_ENDPOINT`. Default: `/sparql`. The update endpoint can be retrieved via the `update_endpoint` helper method.

#### sparql_escape()
The Ruby templates extends the core classes `String`, `Date`, `Integer`, `Float` and `Boolean` with a `sparql_escape` method. This method can be used to avoid SPARQL injection by escaping user input while constructing a SPARQL query. E.g.

```
query = " INSERT DATA {"
query += " GRAPH <#{settings.graph}> {"
query += " <#{user_uri}> a <#{RDF::Vocab::FOAF.Person}> ;"
query += " <#{RDF::Vocab::FOAF.name}> #{name.sparql_escape} ;"
query += " <#{RDF::Vocab::DC.created}> #{now.sparql_escape} ."
query += " }"
query += " }"
```
14 changes: 14 additions & 0 deletions lib/escape_helpers.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
require 'uri'

class String
def sparql_escape
'"' + self.gsub(/[\\"']/) { |s| '\\' + s } + '"'
end
end

class URI::Generic
def sparql_escape
'<' + self.to_s.gsub(/[\\"']/) { |s| '\\' + s } + '>'
end
end

class Date
def sparql_escape
'"' + self.xmlschema + '"^^xsd:date'
end
end

class DateTime
def sparql_escape
'"' + self.xmlschema + '"^^xsd:dateTime'
end
Expand Down
29 changes: 29 additions & 0 deletions sinatra_template/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require 'logger'
require 'rdf/vocab'
require 'sparql/client'
require 'uri'
require_relative '../lib/escape_helpers.rb'

module SinatraTemplate
Expand Down Expand Up @@ -44,6 +45,34 @@ def sparql_client
@sparql_client
end

def sparql_escape_string(value)
value ? value.to_s.sparql_escape : value
end

def sparql_escape_uri(value)
value ? URI.parse(value).sparql_escape : value
end

def sparql_escape_int(value)
value ? value.to_i.sparql_escape : value
end

def sparql_escape_float(value)
value ? value.to_f.sparql_escape : value
end

def sparql_escape_bool(value)
value ? true.sparql_escape : false.sparql_escape
end

def sparql_escape_date(value)
value ? Date.parse(value).sparql_escape : value
end

def sparql_escape_datetime(value)
value ? DateTime.parse(value).sparql_escape : value
end

def update(query)
log.info "Executing query: #{query}"
sparql_client.update query, { endpoint: update_endpoint }
Expand Down

0 comments on commit 6d61845

Please sign in to comment.