Wir wollen über einen (Tokenizing-geschützten) WebService erlauben, frei formulierte
Dazu wollen wir alle Objektbezeichner der eingehenden Sql-Strings mit
Die Regeln
Also mit den Worten der Whitelist kann man höchst komplexe Statements verfassen, aber kein
Beispiel einer Test-Ausgabe:
Also man sieht, dasser alle Worte quotet (
Die anhängende Solution dreht sich eiglich um nur eine einzige Methode, die die Umarbeitung/Ablehnung vollzieht:
Aber ich hab auch eine Frage: Was meint ihr: Kann man das Teil doch noch iwie hintergehen?, also iwelche schreibende Anweisungen reinmogeln?
Testing
Also eine
So kann ich Test-Überschrift und Test-Sql sauber trennen - Beispiel:
Spoiler anzeigen
Daraus wird der Output gebastelt.
Wenn der Output mit dem Inhalt von
Man kann den Input auch ändern, und das neue Ergebnis als Output definieren - s. auskommentierte zeile#15
Aber wie gesagt: Wichtig ist mir meine Frage, ob ihr meint, dass das so wasserdicht sein könnte, oder welche Denkfehler ich in meim Konzept hab.
Select
-Statements von der SqlServer Datenbank abzurufen - aber keine Schreibzugriffe.Dazu wollen wir alle Objektbezeichner der eingehenden Sql-Strings mit
[]
-Quotes modifizieren, bzw. nach bestimmten Regeln auch ablehnen.Die Regeln
- Worte ausserhalb von
''
oder[]
werden als Db-Objektbezeichner gequotet (mit[]
), wenn sie nicht in einer WhiteList aufgeführt sind - Folgende Zeichen(folgen) ausserhalb von
''
oder[]
, werden abgelehnt:@
,--
,;
,/*
,*/
- Nicht geschlossene
''
oder[]
werden abgelehnt. - Geschachtelte
[]
werden abgelehnt
Quellcode
Also mit den Worten der Whitelist kann man höchst komplexe Statements verfassen, aber kein
Update, Insert, Create, Drop, Exec
oder sowas.Beispiel einer Test-Ausgabe:
SQL-Abfrage
- ########### Akzeptiere: beliebiges Sql-Segment
- JOIN HumanResources.[Employee] AS e where e.Name='hanz'
- JOIN [HumanResources].[Employee] AS [e] where [e].[Name]='hanz'
- ########### Akzeptiere: beliebiger Text ausserhalb von '' oder []
- JOIN Huma' -- # ; @ 'nResources.[Employee] [ -- # ; @ ] AS e
- JOIN [Huma]' -- # ; @ '[nResources].[Employee] [ -- # ; @ ] AS [e]
- ########### Ablehne: '@ -- # ; /* */' ausserhalb von '' oder []
- JOIN Human' @ 'Resources.[Employee] AS @e
- --'<Null>
- ########### Ablehne: '@ -- # ; /* */' ausserhalb von '' oder []
- JOIN HumanResources.[Employee] AS --e
- --'<Null>
- ########### Ablehne: '@ -- # ; /* */' ausserhalb von '' oder []
- JOIN HumanResources.[Employee] AS e */
- --'<Null>
[HumanResources]
), ausser sie sind bereits gequotet oder in ''
(zB 'hanz'
)Die anhängende Solution dreht sich eiglich um nur eine einzige Methode, die die Umarbeitung/Ablehnung vollzieht:
Aber ich hab auch eine Frage: Was meint ihr: Kann man das Teil doch noch iwie hintergehen?, also iwelche schreibende Anweisungen reinmogeln?
Testing
VB.NET-Quellcode
- <TestMethod()> Public Sub NoInjectTest()
- Dim outs = New List(Of String)
- For Each xel In Xml.Linq.XElement.Parse(File.ReadAllText("..\..\testInput.sql")).Elements
- Dim title = xel.Attribute("title").Value
- Dim sql = xel.Value
- outs.Add("")
- outs.Add("########### " & title.Trim)
- outs.Add(sql.Trim)
- sql = NoInjectTester.NoSqlInject.MakeSafe(sql)
- If sql Is Nothing Then sql = "--'<Null>"
- If sql = "" Then sql = "<Empty>"
- If sql.Trim.Contains(Lf) Then outs.Add("")
- outs.Add(sql.Trim)
- Next
- 'File.WriteAllLines("..\..\testExpectedOut.sql", outs) ' einkommentieren macht die akt outs zum ExpectedOut.
- Dim rgx = New Regex("\s")
- Assert.AreEqual(rgx.Replace(String.Concat(outs), ""), rgx.Replace(File.ReadAllText("..\..\testExpectedOut.sql"), ""))
- End Sub
testInput.sql
wird als xml eingelesen.So kann ich Test-Überschrift und Test-Sql sauber trennen - Beispiel:
SQL-Abfrage
- <testinput>
- <sql title = "Akzeptiere: beliebiges Sql-Segment">
- JOIN HumanResources.[Employee] AS e
- </sql>
- <sql title = "Akzeptiere: beliebiger Text ausserhalb von '' oder []">
- JOIN Huma' -- # ; @ 'nResources.[Employee] [ -- # ; @ ] AS e
- </sql>
- <sql title = "Ablehne: '@ -- # ; /* */' ausserhalb von '' oder []">
- JOIN Human' @ 'Resources.[Employee] AS @e
- </sql>
- </testinput>[/spoiler][spoiler]
Wenn der Output mit dem Inhalt von
testExpectedOut.sql
identisch ist ist alles gut und das Proggi beendet.Man kann den Input auch ändern, und das neue Ergebnis als Output definieren - s. auskommentierte zeile#15
Aber wie gesagt: Wichtig ist mir meine Frage, ob ihr meint, dass das so wasserdicht sein könnte, oder welche Denkfehler ich in meim Konzept hab.
Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()