Skip to content

Commit

Permalink
Another example, another test
Browse files Browse the repository at this point in the history
  • Loading branch information
deusaquilus committed Jul 8, 2024
1 parent ef87184 commit d796e3a
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,24 @@ in an SQL-injection-safe way. Inspired by Scala libraries such as Doobie and Zio
delays suspends the "$dollar $sign $variables" in strings in a separate data structure until they can be
safely inject into an SQL statement.

TODO large diagram about teral variable suspension
```kotlin
val ds: DataSource = PGSimpleDataSource(...)
val ctx = TerpalContext.Postgres(ds)

// Let's try a pesky SQL injection attack:
val name = "'Joe'; DROP TABLE Person"

// Boom! The `Person` table will be dropped:
ds.connection.use { conn ->
conn.createStatement().execute("SELECT * FROM Person WHERE name = $name")
}

// No problem! The `Person` table will be safe:
Sql("SELECT * FROM Person WHERE name = $name").queryOf<Person>().runOn(ctx)
// Behind the scenes:
// val query = "SELECT * FROM Person WHERE name = ?", params = listOf(Param(name))
// conn.prepareStatement(query).use { stmt -> stmt.setString(1, name); stmt.executeQuery() }
```

In addition Terpal allows you to decode the results of SQL queries into Kotlin data classes using
the kotlinx-serialization library.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.exoquery.sql.postgres

import io.exoquery.sql.*
import io.exoquery.sql.jdbc.Sql
import io.exoquery.sql.EncodingSpecData.insert
import io.exoquery.sql.jdbc.JdbcEncodingBasic.Companion.StringEncoder
import io.exoquery.sql.jdbc.TerpalContext
import io.exoquery.sql.jdbc.runOn
import io.kotest.core.spec.style.FreeSpec
import java.time.ZoneId
import io.exoquery.sql.EncodingSpecData.TimeEntity
import io.exoquery.sql.EncodingSpecData.insertBatch
import io.exoquery.sql.examples.Simple_SqlServer
import io.kotest.matchers.shouldBe
import kotlinx.serialization.Serializable

class InjectionSpec: FreeSpec({
val ds = TestDatabases.postgres
val ctx by lazy {
TerpalContext.Postgres(ds)
}

beforeEach {
ds.run("DELETE FROM Person")
ds.run("INSERT INTO Person (id, firstName, lastName, age) VALUES (1, 'Joe', 'Blogs', 123)")
}

@Serializable
data class Person(val id: Int, val firstName: String, val lastName: String, val age: Int)

"escapes column meant to be an injection attack" {
ctx.run(insert(EncodingSpecData.regularEntity))
val name = "'Joe'; DROP TABLE Person;"
Sql("SELECT * FROM Person WHERE firstName = ${name}").queryOf<Person>().runOn(ctx) shouldBe listOf()

// This would cause the relation to be dropped
//val res = ds.run("SELECT * FROM Person WHERE firstName = ${name}")

Sql("SELECT * FROM Person").queryOf<Person>().runOn(ctx) shouldBe listOf(Person(1, "Joe", "Blogs", 123))
}
})

0 comments on commit d796e3a

Please sign in to comment.