>> Helen Wang: Good afternoon, everyone. It's my pleasure to introduce Martin Johns.
Martin came from Germany and he is a PhD candidate who's expecting a PhD in just a couple of months.
>> Martin Johns: Yeah, I was.
>> Helen Wang: Yeah, So Martin is going to talk about Secure Code Generation for web applications.
>> Martin Johns: Thank you, Helen. Yeah. Great that I'm here and so this is the outline of the talk, it's rather generic. I have like three slides to give you background information about myself so that you know who's talking to you and what I've done before and where I'm coming from.
Then we will have a brief look at the back class of string-based code injection, the text of
Cross-site Scripting, SQL injection and so on. And I will try to show you how we try to tackle or we analyze this back parent. And then number three's the main part and we'll be going off the same outline later where we talk about -- where I talk about our solution or proposed solution to the problem.
Okay. So who am I? I have a strong background in software development. So pretty much until I went to university to go for my PhD full time, I've worked in a lot of different companies, wrote a lot of code and pretty much all the code I assume was really, really insecure. But this background, at least I hope gives me little bit insight in the mind of codecs and what the requirements are and what they might want to use and what not.
Then in 2005, I joined University of Hamburg, back then Professor (inaudible)'s group to work on the project Secologic, was a research project funded by the German government was investigating the state of the art in software security. And while my assigned focus was more in the C space, my interest rather quickly shifted to application security in space because there was so much going on within securities that were actively exploited and unsolved.
After Secologic finished, I was in a couple of short-time research projects for Siemens with FFMP Research and right now I'm doing project management for a project together from within other partners.
So what have I done on what I'm talking about today? And so I looked -- for one I looked into mechanisms that should provide us with a second line of defense. So web
application security problems are rather frequent and while there are approaches to detect such vulnerabilities, back when I started there were pretty much no approaches to -- at the user or at the application to mitigate the exploitation if there is a security vulnerability. So I looked into cross-site scripting, Cross-site Forgery and attacks on the internet and looked into how are these -- how does these attacks function, what are the requirements and how are they executed in the broad-end application paradigm and how can we change this paradigm in the most computable way so that the attacker is not as almighty as he was before our approach.
And also we did couple of things in the space of detecting and preventing application problems. So I can't -- last week I was at ACSAC and presented our approach, surface-site detection of cross-site scripting problems by HTP monitoring. So we took lessons we learned from the intrusion detection, which is rather mature discipline and tried to apply it to cross-site scripting detection and together with Siemens we looked into static analysis and what the state of the art is there and how to benchmark such tools and what are the open questions.
And also we did a preliminary project, which led to the topic of today's talk on detection of string-based code injection text using a variant of instructions at randomization. But this is -- if you have questions about those things, come to me after the talk, I'm happy to talk about those.
So today I will talk about our approach towards language-based prevention of code injection vulnerabilities. Before I talk about our -- how we have tried to solve the problem, we have to revisit the general back pattern of string based code injection and isolate what we think is the main root cause for those vulnerabilities.
So if you look at the application paradigm right now, you have -- usually we have to look at here infrastructure. And what's special about this, you have a hydrogenous amount of different computer languages that are employed by the application at the moment.
So you have the -- what we call native language. This is the language the actual application was written. It's PhD, Java, c Shop. This is the language that does most -- implements most of the application logic.
And then we have rather hydrogenous and large amount of what we call foreign languages. So those are computer languages, query languages, structured languages, general-purpose languages, like JavaScript, that are assembled on run time by the native application to be sent, then to external operators and to be executed and operated in the external systems and the database SQL by HTML on the web browser.
And the main observation if you look into backtrack of all this closure and stuff like that, and this string-based code injection, which affects all sorts of foreign language assembly, and it's always the same back pattern. And if our -- it affects all -- every time some computer code is assembled dynamically within the native application, you're going to encounter this back pattern. And if you look at backtrack, you see you're going to encounter this back pattern.
So you will detach the process scripting SQL injection, shell injection from the injection, path through, S part injection, LDEP injection, (inaudible) injection with SMPP injection.
Pretty much everything is susceptible to this injection take. It's always the same.
How does it work? Your dynamic code assembly, which is string-based in the current practices and applications, and we're going to get some data from the outside through an
HTP request and in this case the password the user provided contains some unexpected characters. Those characters are blindly echoed into the resulting SQL statement and in this case this is the classical example for SQL injection.
What is the problem? Why does this happen? It happens because we have a mismatch in perception that is happening. The programmer, while he's writing his application, he has to interact with the database. He's thinking, okay, I'm doing -- maybe he's even aware that he's actually writing computer code, but still he thinks, okay, I'm writing this
SQL statement. So my SQL statement consists of a code portion, the static part, and I want to enhance this static code portion with some data values so that I can get the information from the database that I wanted.
The problem is that the database operator has a completely different view on -- let's call it data and code separation of the elements. The interpreter interprets this foreign code statement strictly after concerning the native, for foreign language it's grammar. So it has a couple of code fragments within the statement. It has a couple of data fragments. On compile time this string-based variable is unknown whatever it contains and so in our case of the code injection attack. So this is assumed by the programmer to be the data portion, but depending on which (inaudible) comes in. There might be data in there, but also there might be fragments in there that are interpreted by the database to actually be code.
So what is the problem? This way of string configuration and string serialization before sending it to the database revised in implicit prime code creation. So the programmer has to rely on the assumption that he's doing something correctly with saying, okay this, is the string, take it, execute it, let's hope everything is good.
Okay. So we want to get rid of this and our initial motivation was we wanted to look at how can we change the way we program our vet applications in a way that only programming language we're going to get rid of this back pattern without to be too invasive. I'm going to have a slide where I talk about the objectives, so we didn't want to invent a new program language. We just wanted -- we wanted to change the smallest subset of existing methodology to get rid of the back pattern, but nothing else.
So general approach. At first we tried to isolate what we consider to be the root cause of the back pattern and the root cause, as I'll hopefully convince you of this and you probably already knew, that we use the string type the (inaudible) string type for code assembly. And the string type, even if the programmer knew what he wanted to do, even if the programmer wanted to add his foreign code with more semantical information for later processes to understand what his intent was with the string assembly. He isn't able because the string is just a dumb sequence of characters and therefore after the string assembly everything is less (inaudible) now.
Also, a second root cause, which is secondary, is that after this code has been assembled it is transferred to the external interpreters to the database on the net browser through unmediated direct interfaces. They just get the character screen and interpret it.
As I already told you, we want to solve this problem on a programming language level, so our order was that even if the -- but we wanted to force the programmer to write secure code and so not to make a conscious decision. So the current practice right now is tell the programmer, okay, you have to sanitize it in code and you have to make sure that everything is okay before creating the strings and programmer fail at this and considers a backtrack.
And instead we wanted to, as I said, change the general programming patterning as far that if you use our method you should be secure by default. And yeah, so the question we had was how do we need to externally modify the existing practices to reliably prevent
(inaudible) class. Methodology is then we tried to remove the things that we considered to be the root causes through the points down mainly to exchanging the string type for code assembly through something that is better suited. And as the author thought also we have to get rid of all those unmediated interface to the external interpreters, otherwise we would provide the programmer with a shortcut or a back door towards writing insecure code even if you don't want to. So we want to have a reliable, secure system.
Okay. Our design object is, as I told you background in programming and I have interacted with a lot of programmers, and most of the programmers, they don't really like
to change. They learn their stuff, they learn their languages and they are really good in this and they're -- therefore, even in the young field like the applications, they are rather reluctant to change the way that it's done. Therefore we didn't want to invent a new language. We wanted to develop general concepts that should be applicable with as least effort as possible for any modern programming language, at least any modern object-oriented or procedural programming languages.
And also we didn't want to change the font's index. If you look at special domain, languages like SQL or XML, the syntax of those languages has been defined and created very carefully to solve a specific problem. By changing the syntax we might willingly or unwillingly change the way those languages were designed in the first place and this would also hinder a adoption.
And third and then is also especially when I've been working together with SAP for practical implementation of the approach, programmers really like the flexibility of the string type. So creating assembling for a code with string type is a rather comfortable and powerful method. So you can put code together, you can rip it apart, you can apply filters on it and you can jumble it around, you can index it. And so the string API has proven to be very nice thing for programmers to create, especially nontrivial-like big
HTML pages and stuff like that.
So all these design objectives that we listed before we started developing output boil down to we wanted to keep the programmers happier so we have at least a remote chance that somebody will use what we are doing.
So taking our general methodology and our design objectives that I listed we can isolate three key components that we have to design, implement and resolve. So for one most important we have to design and implement a new data type that is more suitable for encode assembly and the string type we have to integrate this data type together with the foreign syntax in an unobtrusive way into the native code so that the programmers will be actually be willing to use our abstraction and we need an abstraction layer which has an interface that receives this data type and then safely creates secure foreign code out of the data type that we sent.
Okay. So the main part of this talk or the -- so the more interesting part of the talk is devoted to the data type. Because pretty much the key, it's the center piece of our architecture. And within the data type because is really offer to write lower level data type. We call it FLET. It's called foreign language encapsulation type and for our FLET we have a couple of requirements. This should be obviously part of the native language and it also should be able to encapsulate foreign code of arbitrary length and complexity.
And so we aim to create syntactic means to integrate or to cover the complete foreign syntax and not a subset. This is mostly important to us because otherwise we would still require the legacy interfaces for special purpose requirements.
And third, to actually achieve the security requirement or the secure properties that we aim at. Our fleet should provide strict federation between data elements and code elements in the foreign language. We'll come to this -- what we mean with data element and code element in respect to foreign syntax, I will explain it a little bit later what we mean.
So what we aim is that all code elements that are created on run time by the native language are all foreign code elements should be created explicitly. So with the string -- as a set versus string our code creation is implicit. Take the string and think of it as code and whatever is in this string should be executed. And there's no verification that the string really contains the code that I wanted to create.
Instead we want to get rid of this problem, but we want to bring the programmer to say, I want a select statement. Not -- as SQL segment we want select our statement which selects from a certain table with a certain condition. And I don't want (inaudible) selecting there. I don't want an update or anything. I really just want to select. I will come to this a little bit later, too.
Okay. Before we come to the practical limitation, now a couple of slides on formal consideration. So we want to invent or we want to extend the native languages type system. And we want to have certain security guarantees. So to have at least a guideline from the formal true set that is given to us, we looked into type theory and how to model type systems. And we looked into prior work that use this so we can -- don't have to reinvent the view.
So we looked into type systems and the major thing that people do with type system security is enforcing confidentiality requirements. It all dates back to the (inaudible), which probably everybody if you know really good, but for computing sake (inaudible) hardware is this classic multi-level security model with two properties and in this case two confidentiality classes, public and secret. And through these two information constraints formulated or formulized by those two properties, both direct and indirect flows from secret information to public places are prevented.
Then Denning-denning(phonetic) '77 showed that this can be enforced by static program analysis and in '96 Lopan(phonetic) and Smith formulized this approach using type
theoretical method and another type system so that they could, by defining public as a subtype a secret, they could prove that if the type system is enforced by the time that those information flows don't work anymore. And there is lots and lots of work that is based upon this paper.
The dual model to (inaudible) hardware's (inaudible) model, it is not -- it enforces in two reconstraints in confidentiality constraints by preventing flows from low intrusion, which is just a data, to high integrity places. It works pretty much the same thing, but also has the two Axioms for indirect and direct information flow and it can be modeled completely analogous too, so you can basically use the same typing rules as with the (inaudible) model to enforce this system.
So how could this apply to our case? We can -- so we said we don't want any code elements in our foreign syntax, whatever these code elements may be. We don't want any code elements in the front syntax to be defined by data elements. This can be obstructed into an information flow policy. So by defining the code element to be of high integrity, I think this is a requirement that everybody could agree to. So when I'm creating code it should be executed, I demand that this code is of high integrity. And also we define data elements to be of low integrity. This is also a thing totally (inaudible) data elements can come from malicious people and dubious origins, so they should be of low integrity.
And so by preventing those flows from low integrity data elements who high integrity code context, we should be able to get rid of this bug class. And also our problem too that we have to solve is simpler than the confidentiality case because we only want to prevent direct flows. We only want to prevent when the attacker is able to directly inject code information because indirect flows from -- that where data elements indirectly influence the creation of code element is something very essential to the applications.
Take for example Aveki(phonetic) that comes in Aveki(phonetic) mark-up data which is then translated into HTML marker. Therefore, this is the definition of an indirect flow from data into code elements. Therefore we have to allow this or at least in certain cases.
And for this reason we only have to concentrate on this star integrity axiom, which is responsible for preventing their -- preventing the direct flows from low to high.
Good. So far, so good. Now we have to think about -- okay we talked about code elements and data elements. Now we have to be -- get real and to say what are in our model data and code elements? What we need is a mapping or something that we can apply from the concept data code to the single syntactic elements of the front syntax. So again our SQL example. We decided to apply this mapping on a token level -- token
level abstract class actually. So we looked at a couple of existing foreign language grammars. So we looked at the HTML grammar, JavaScript grammar, SQL grammar, grammars for pass and URL classification. So everything that is frequently susceptible to code injection text and we derived generally token classes from these grammars.
And we derived three different classes. For one, those grammars have static elements.
Static elements are tokens that are defined completely and statically inside the language of grammar. So collect from where -- the language's keywords and also meaningful punctuation, in this case star, equal and dash. Those are tokens that are hard coded, if you want to say this, in their language grammar.
Then you have identifier elements. In this case the table name and -- or the column names and also something like variable counting. Those are front syntax elements that are completely defined in compile time. So if you write foreign code you know which function you want to call and in which variable those data that you are computing should be end up.
So those identifiers, the first class is usually values. Some values are when you do foreign code assembly usually differ from foreign code enunciation to the next, otherwise you wouldn't need dynamic code and dynamic code assembly in the first place. So everything which values might vary on run time, strength and adjust in the case of HTML, the values of HTML attributes and so on.
So how do we map this now to the data and code abstraction? Everything that might lead to privilege escalation on the adversary side, so everything that might bring the adversary to more privileges than he is supposed to have on a syntactical level, if he influences this, has to be defined as code. So there's identifier in the static element and everything that should be okay to be defined by dynamic interpreter data are stated in this case value elements.
Okay. So putting this all together and we need for our type system, our expansion that we are proposing, we need for one renewed new data types that are responsible for representing the syntax -- the foreign syntax elements within the code that the programmer writes. So we have code -- we introduced code token and data token elements. A code token object substantiated represents exactly one syntactical token element within the foreign code. And we introduce the FLET as a really dumb mere container type, which represents the token streams. So the FLET just as sequence of code tokens, data tokens, code tokens containing for example the key words and key word punctuator and an identifying or variable name, the data tokens containing all the values that are supposed to end up in the foreign code.
Next then we need two integrity classes because we want to use the (inaudible) model to formally ensure that we're doing the right thing, therefore we will have two integrity classes. CT and DT. CT for code token is assigned to our code tokens only. DT is assigned to everything else, to for one the data token element and also to all native data types that are provided while data exists within the native language and by defining the sub-type relationship the code tokens are subtype of data tokens and using the subtyping assignment rule from (inaudible) and Smith, we can prevent all direct flows from DT to
CT. This is provable and compared to more sophisticated types of work this is rather, rather, rather easy, so it is embarrassingly simple to prove, so therefore I spare you the details.
But you can view -- save this from type for introduction symbols and fraction to the typing rules and the bottom line is as all data or all values that are controlled by the adversary and does the application through a native data type and all native data types are implicitly tied to DT, they never can in the context in the code context that is type of CT flows, they never can be used to substantiate code token elements.
Finally, the model of the FLET. FLET is a simple type confirming container containing dumb sequence from token streams and thus by implementing those types, data types, integrity types, we can ensure that within the native language our data elements and our code elements are cleanly separated and will never be mixed up. Therefore, even if the programmer makes a mistake in the way of thinking, he is not able to create implicitly code token based on data tokens or data information that was given on run time and as the FLET doesn't do anything interesting about keeping the stuff and passing it on to the detection layer within the native language all data and code elements or tokens or types are cleanly separated without any means to dilute the separation.
Good. This was our formal considerations if we -- we wanted -- we did this mostly to ensure that what we are doing is actually provable in a semi-provable way doing that what we want it to do.
Now we come to our practical limitation that we did together as a (inaudible) research. In this we talk about the language integration and the abstraction layer, which are more like engineering tasks.
And our integration target was for one etched in the JavaScript, so we wanted to prevent cross-site scripting attacks or we wanted to aim at cross-site scripting attacks. Native language was Java. The J2E application server (inaudible) more precise. And we choose X cross-site scripting for the following reason. And for one cross-site scripting is
ubiquitous right now, so they're pretty much -- there's hardly a single (inaudible) application vendor that hasn't had a cross-site scripting problem in the last 12 months and there's hardly a single open source or closed site -- closed source, application project that hasn't had a single cross-site scripting problem. So Cross-site Scripting right now is everywhere.
And what makes it interesting from viewpoint of assembling foreign syntax is that we have two distant foreign syntaxis, etching and JavaScript that are interwoven mixed rather widely within our foreign code. And also because the browsers are doing rather good job pausing and displaying broken HTML, we have a lot of many nontrivial injection attack vectors that we have to -- would have to consider once (inaudible) otherwise.
Good. Let's come to the language integration. This is a question, how do you in practice, so we define what the properties of our FLET type should be, now we talk about how do we flow it, how do we integrate the foreign syntax in the native language?
There's a lot of prior work that we can rely on. We will discuss it rather quickly so that we can in both API, you can try to extend the native grammar or you can use a preprocessor.
So the API approach encapsulates the foreign code within the API codes to in this case the FLET type and the API codes. Then say the FLET type, okay, take this token. It takes this token to this token. This is closely related to stuff for example like the XML domain API or something comparable has been proposed as obscure. This has some nice properties, so you can implement this rather easily for any existing application server and you don't have to change anything, it's just a programming language. But you end up with a really ugly incumbent cumbersome syntax, so that it is hard to maintain and debug that probably a new programmer will use the -- new programmer will use this for a nontrivial code generation.
On the other side of the on abstraction, this is something Microsoft has done really nicely, is that you can try to extend the native language with grammar. So in the (inaudible) project in Microsoft, they showed how to promote XML and SQL to be first-class members of C Shop, so that you can write in C Shop or any other dot-net language just
XML or SQL dialect to get real data.
So this is something you actually really want to do. So this is what the codecs would like to do and what also would serve our purpose very nice. You still -- you have a strong mimicking of the foreign language of syntax if you do it right, but also you have stuff like good support and compile time checking if the foreign code is correct and the programmers don't have to be trying that hard.
The disadvantage is this is a rather heavyweight approach to solve this problem. You have to go rather deeply into your native language. You have to change your native compiler or the (inaudible) process DT. You have to do more deep integration of the firm data types to the native data types and so what have been done by EarthLink Q.
So I will be interested later on in talking to people that work on this, how feasible this is for other languages besides query languages and XML.
The third path is somewhere in the middle. It tries to combine the advantages of both its user of the pre-processor so you encapsulate your foreign syntax within unambiguous syntactic markers and our example, dollar-dollar. So everything that is encountered by the pre-processor, which is between dollar-dollar markers will be translated into native
API in the presentation. So the programmer is more or less just writing the foreign code as he has used it, but it is translated into the internal API and therefore it has the advantages of PIE.
The API approach this also has a couple of disadvantages that you have to live with. The biggest is that the code that is actually going to get compiled is not -- doesn't equal the source code, so it's not what the programmer wrote. And so if there are problems with the code that has been produced by the pre-processor the error messages are really horrible. So if any one of you ever has worked with C-Plus-plus, I think you know what horrible, horrible error messages And c-Plus-Plus is exactly this problem. Yeah, I think the rest is pretty obvious.
Good for all practical reutilization only because we want to do something that we were able to do with limited resources. We choose, not very surprisingly to use the pre-processor approach. And so the preprocessor -- - so the programmer writes this source code mixed between Java HTML JavaScript with the syntactic markers. The pre-processor locates all the foreign code positive and code it according to the foreign language's grammar and creates the token type and the tokens and translates all the foreign token codes tokens into the appropriate API codes that create the token objects within the FLET type and this is how our API designer ended up.
So we wanted everything to be as explicit as possible. Therefore, we looked -- also as required as normal we looked into what other stricter syntactical requirements for the single object. So for the static code elements like language keywords, technical stuff, there are dedicated API codes to create such types than their limited dynamic flow calls to create. Identify types in the data elements just end uptaking arbitrary data values because they only (inaudible).
Then in the pre-processor, there's an example for the pre-processor language we need -- we had to come up with a very, very simple meter syntax because within the pre- processed code it has also been the opportunity for the programmer to include a dynamic data values and native data values. This is translated into the Java API version and through simple syntactic markers, native data type in this case, the native name variable ends up as a data token within their FLET.
Okay. For the -- as I told you, we wanted to make the programmer a nice home and we build again a rather simple, but powerful meter syntax for simple FLET operations, such as (inaudible) combination and enunciation of FLET objects, which closely was mimicking the string operations and so continuing two strings with middle correctors and also we outfitted the FLET from API that mimics the string API for splitting, surging, iterating
(inaudible) their FLETs.
Finally, the abstracting layer, I go over this rather quickly because it's not that interesting, but it had to be implemented in source. So if you want to build an abstraction layout, which takes the FLET type and translates it into a representation that is understood by the interpreter and you have to decide where to put it. You could put it into the native language and spit out here corrected base representation. You can have something immediate so that you have a couple of native languages or giving it on the FLET type into the abstraction layer and have a central point for processing the XML language.
What would be best is if you could include the translation process between the FLET type, which already contains the code in a pre-parsed or almost parsed tree like version.
So a lot of the parsing process that has to be done in external integrater already has happened in the preprocess in the native language. So the ideal -- in the ideal case we will just transfer the FLET information and the external interpreter would use the data and code information between the FLET for secure operations. So like it did with (inaudible) with preferred statements, for example.
In our practical limitation to us, you can't do this in the browser, you would have to change browser from accepting XML code into FLET code and we didn't have the resources to do so, therefore, we built an abstraction into a native language, which had the nice effect that we don't have any deployment problems and I will show you why in a second because it wasn't J2E and J2E was really nice in this.
So the last step of the FLET has to reserialize the FLET into a string-based representation of the HTML code. We did this because in this case our -- all our code or data context which we encounter in this case offer a possibility to encode data values into a nonexecutable representation, therefore we don't really have to think about what is in
our data values, we just transform them into the representation that provides -- that prevents the browser and depletes them of anything else as data. So with HTML entities, percent in coding and within JavaScript depending on the context, but usually with
(inaudible) string from (inaudible). This way even if they take it twice to trick us into including some syntactical elements that could be code, we won't -- they won't be executed.
And another avenue we kind of explored was comparing parse trees as explained by Su and Wasserman, but I'll skip over this.
>> Question: Could you compare that, compare with Su and Wasserman's approach?
>> Martin Johns: Yeah, well, this is -- so the observation that Su and Wasserman made was really nice, I think. I don't know how many of you know this, (inaudible). They said, okay, we have -- if we compare the parse tree of different code statements that we have with the parse tree of a foreign code statement that includes string -- the code injection attack, then we note that in this case the parse tree is different and like if the data place holders in this parse tree only contains data the parse tree is static from instantiation to instantiation of the foreign code syntax. But if you have the code injection attack then you -- the parse tree differs and therefore by different -- by matching the resulting parse tree, you can see if the code injection attack has happened and if there is something there you should be concerned of.
And this is really easy to do with our approach because we already know which of our elements are data and by replacing the elements with dummy elements that reliably don't contain anything code-like, just little static RR strings, you have two different parse trees and if they match, you know, okay, no code injection attack has happened. What's that?
>> Question: That is if you properly develop a notation for most of the -- for most of the data?
>> Martin Johns: With this type we already know which is the data. This is ensured and enforced by our data type.
So we already know, okay, this is data and this is not data. Here we have to think about it is how do we treat the data within the FLET so we don't introduce in the last minute injection variable, so this is pretty much implementation.
Yeah?
>> Question: It seems that your FLET approach is an instanciation of the Su and
Wasserman technique?
>> Martin Johns: No, I don't think so. So Wasserman has an implementation that relied on (inaudible) attaining, so they still -- Su and Wasserman still rely on string-based code injection, string-based code assembly. The only thing that resembles is when we use in the last (inaudible) they are. At the last moment, if we look here at our resulting FLET object and the contents, then we can use their mechanism to see if somebody attempted to do code injection attack.
>> Question: Maybe we should take this offline, but I guess my perspective is that Su and Wasserman required the parse tree remain the same, you know, you shouldn't change with this coding, user input --
>> Martin Johns: Oh, yeah, it's truly comparable, otherwise I wouldn't have mentioned it here. So they're -- yeah.
>> Question: Yours -- you're limiting to the case where the parse tree doesn't change with respect to the, you know, data or code and you have a bunch (inaudible) parse tree is.
>> Martin Johns: I know they (inaudible). I think we have a (inaudible) because one of the things if they assume the Wasserman approach is that if the attacker is able to influence the identifier elements of your code, for example the table lengths of your SQL statement, the parse tree doesn't differ. So take an example which is not that country that depending on the execution context, the prefix of an SQL table that you access differs. So Edmond users were the regular users. And the prefixes are controllable by the attacker so that he can change the user prefix to Edmond prefix because of some logic error between the application. Then he's able to do some privilege operation on the admin user table without changing the parse tree.
In our approach, something like that is not possible because we can treat and identify elements to be code and they are not accessible to the -- not definable through dynamic data at all directly. Yeah.
Okay. Communication and implemented this together with research as a J2E filter providing a FLET interface and the legacy string interface adjustment to a lock file, so that we can ensure that no legacy in insecure code -- in securely generated code ends up within the HTML code. We did evaluation. We evaluated the protection properties of our approach by creating a really insecure test (inaudible) accuating(phonetic) blinky echoing
back and tech provided data into different for encode contexters and ran a list of well-known innovation techniques against this software to ensure that none of the attacks actually happened.
We also verified that our approach is usable in a relapsing area, therefore we took a mature, rather large, J2E application. In this case a J2E Wiki and adapted it or rewrote it to use our FLET semantics. JSP Wiki had about 70,000 lines of code and seemed to be a good innovation target for a couple of reasons. For one it contained the version that we used. It contained a rather large number of different cross-site scripting problems, stored cross-site scripting, as well as reflective cross-site scripting and it -- because it is a wiki, it contains a lot of nontrivial generation of dynamic HTML content and for performance evaluation in 2000 has the (inaudible) user database back in. It's optional, therefore, when related to our performance evaluation we don't emulate the database performance, but actually the -- are implementations.
We profit this JSP wiki to our FLET approach and out of the 365 about 103 or plus-minus one or two, file had to be touched. This took me aside at the plotting and took me about a week, so it wasn't that hard. Also because JSP wiki is rather well written, so it's a badly written application it will take considerably longer because you have to take every single string element in your application and you have to decide will it ever end up in a code context? Will it ever be used to generate HTML? If so you have to translate it to FLET semantics.
The result was that all the cross-site scripting problems that were in the application were resolved after putting into FLET without even looking where in the code those cross-site scripting problems were. We just parted it afterwards -- afterwards very (inaudible) cross-site scripting problems were gone just because we now use a different paradigm to build the foreign code.
Okay. We go to performance evaluation, understand what that means and ended up with run-time overhead between 10 and 25%. What I thought was for a reliable security, okay and perhaps implementation of the approach okay result. Good.
Let's come to the conclusion. So I hope I have convinced you. Otherwise, I'm looking forward to the discussion that we -- using our approach, we reliably prevent string-based code injections so that the attacker and the programmer, even if he tries to (inaudible) secure code shouldn't succeed so because we don't have any -- a path from string of unsecured string data to code token objects.
Using all our practical limitations we've shown that it can be easily implemented for existing languages, frameworks and server, application servers and we allow -- so it doesn't really matter how complex the foreign syntax is, the complete coverage of the foreign syntactic elements is achievable rather easily using our approach. We only have to identify using the firm grammar, which understanding the identify elements, everything else comes pretty much naturally. And we -- therefore, we can apply it to arbitrary foreign languages type. So we can model query languages, markup languages and the purpose interestingly new hybrid language, such as HTML JavaScript and furthermore, this is -- might be subject of future work.
And so building a pre-process and an API is pretty much done. So it's really straightforward if you have a grammar and a mapping between elements of the grammar and the data code categories. Therefore, based on parse-parse compiler-compiler approaches that already exist, automatically generating for a new foreign language, an
API and preprocessor can be rather easily atomized so -- because it's pretty much just take the token elements, translate them into API code and pass the existing code for a pre-processor markup.
Okay. So this is -- with this I conclude and might be looking forward to some discussion.
>> Question: Yeah. Which values in the language have high integrity and which have low integrity? Like is the string literal automatically high integrity --
>> Martin Johns: No. They all -- all values are low integrity. So the only high integrity things are static elements are static elements of the foreign syntax. So all the keywords, so -- basically everything that you don't the attacker want to control -- let the attacker control to prevent code injection attacks, you define to be high integrity.
>> Question: So since it's not a matter of how things are manipulated in the program, it's the string values themselves? Like Martin would be low integrity, but Select would be high integrity?
>> Martin Johns: Oh, so the screen select would be low integrity, as well. Only the token, so we have this new -- two new native data types that represent foreign token elements within our language. So --
>> Question: But so in some of your examples you said things like new FLET and then you pass in the string Select.
>> Martin Johns: I see. Oh, I should get rid of this example. You're right. This is most just an example of a dumb API representation of pre-processor, but it wasn't a FLET example. Good point. Let's go back to the --
>> Question: The pre-processor --
>> Martin Johns: No, (inaudible). Wait a second. We go back to this. So the output of the pre-processor is here and it should be, if I haven't screwed up, should be entered to the requirements that are formulated. See. And so in this case, in the example above, we have code token that's the B attack. We have a data token, it's a hello string. We have a data token that's a dynamic string. And we have another code token, it's the
(inaudible) attack. Translated into the foreign language -- into the API, we have a static call that creates code token object for B. Then two calls that create data tokens for the string silo and for the dynamic string. And we have the last API call that again calls code token for the closing (inaudible).
So in this case we don't have any data flows from low integrity string data to high integrity code.
>> Question: So a finite number of high integrity tokens --
>> Martin Johns: Oh, yeah.
>> Question: -- in order to generate this?
>> Martin Johns: And you've got the static elements in your native language around in the grammar. In the foreign language's grammar, the static elements are finite and therefore you have a finite number of API codes that create those things.
>> Question: So doesn't that generate some sort of a syncing issue?
>> Martin Johns: What is syncing?
>> Question: Well, where, you know, if your language is evolving, you need to then sync new keywords into the pre-processor.
>> Martin Johns: Oh, yeah, you would expand the API with the other new language version. But this is rather lightweight. So adding a couple new API codes is really easy compared to if you go with what I've outlined their -- their approach way to try to include
the foreign grammar or the foreign syntax into your native language, where you have to change complete pattern process.
>> Question: And it just -- it's not a management issue then, I mean that you have to then make sure that you have the right versions?
>> Martin Johns: I think you will always have management issues in this direction, sure.
But I don't think --
>> Question: I mean it just adds another one to all the ones we already have, right?
>> Martin Johns: Well, so you have to wait -- do you want to -- if you want reliably secure code --
>> Question: I get that. I'm just saying that, you know, because not only do you have to make sure that the programmer is okay with this, right, you have to make sure your IT people are okay with it, too, because they're installing it.
>> Martin Johns: Oh, yeah. I think the programmers shouldn't be this big a problem.
The bigger problem might be the people that have the deployment requirements because they have the work to do. For the programmer, if you look at this, I think this is rather good example because you see, for the program it doesn't really change anything. If he has now double quotes or dollar syntax, it's the same parenting that he uses, so it is pretty much as he would still would use strings, but in a secure way.
>> Question: (Inaudible) dollar centered is what you added to the original code?
>> Martin Johns: So this dollar syntax here is our -- represent the syntactic markers that tell the pre-processor, okay, here starts foreign code. So everything else in pre-processor goes through the Java code and whenever he encounters such syntactic markers, he starts the parsing process and translate what is between such syntactic markers into the API representation, then creating the token object in the data, token object --
>> Question: Marking then is a foreign code?
>> Martin Johns: So between the -- so the foreign code is --
>> Question: The dollar sign --
>> Martin Johns: The dollar sign isn't just our meter syntax. The foreign code is the
HTML code that is embedded into the JavaScript -- the Java code.
>> Question: So again this is just, this is more of a bad day as a quick-fix scenario, right?
>> Martin Johns: (Inaudible) --
>> Question: Going forward you really want to have this in your native --
>> Martin Johns: Probably should. --
>> Question: -- more than anything else.
>> Martin Johns: Yeah. I think I've solved this. So this is pretty much, this is something feasible. So you can do this rather quickly and rather reliably, but -- so if you're able to pull this off for really complex languages and with good language coverage, you should go the path and expand the native language the way the Link Q project in Microsoft is doing it. I think this is remarkable work.
>> Question: So with like JavaScript that has a dynamic evaluation feature (inaudible) -- executed?
>> Martin Johns: Yeah.
>> Question: Is the pre-processings as (inaudible) or does -- do you need to cover personally the (inaudible) processor every time you --
>> Martin Johns: To solve though problems, yeah, so Eval is a big problem for stuff like this. So to solve those problems you won't need to add a FLET abstraction within the
(inaudible) JavaScript language, so this is out of scope for our solution.
>> Question: (Inaudible) if you have got to do Script you would have to essentially two --
>> Martin Johns: Yeah.
>> Question: (Inaudible) --
>> Martin Johns: Yeah. Eval is a problem. I think usually eval is a problem.
>> Question: You still have a problem where if that you generate the code from the
HTML it could be interpreted as browser risk as JavaScript because of encoding tricks.
You know, in a semi- parameter that's got -- that's (inaudible) actually could be interpreted by the browser parsing as JavaScript.
>> Martin Johns: So, yeah. If you don't implement your serialize -- the fine serialization step, if you make mistakes there, then obviously, yes, you can --
>> Question: Symbolize the HTML, that's utilizing the two -- it has to emulate the behavior of all processors.
>> Martin Johns: I think there are a couple of -- so if you choose to encode all text elements in this nonexecutable -- nonexecutable representation using complete HTML entities, I don't think there's any evaluation technique that the attacker could use that would break that to include HTML markup or JavaScript markup.
You only need -- the only thing that abstraction and especially with HTML, the only thing
-- so all the invasion techniques usually confuse the (inaudible) code -- the (inaudible) process within the application by two general techniques. The one is giving totally broken markup that is -- can't be understood by the (inaudible) project and therefore produces errors. Or otherwise confusing the (inaudible) process in which specific code context a certain data value is injected because it's totally different if you have a data value injected into HML context, into URL context or into a JavaScript context and then all those contexts, it is essential that you use different encoding techniques. But so the first -- the first thing attackers use, so the broken up -- the broken or (inaudible) HTML marker can't help you because all the markup that is supposed to be on that will end up in their code later on will be generated out of our code tokens.
So this is the first thing. The other things, all HTML is created explicitly. And the other thing is that because we already know which HTML text, which code context we are because the FLET contains everything in the preparsed form, we can reliably ensure that we know in which context we are and therefore we can reliably choose the correct encoding method, HTML entities, URL specific coding or JavaScript encoding.
>> Question: Right. It shows that on the slide, right?
>> Martin Johns: Yeah.
>> Question: So you had a string that (inaudible).
>> Martin Johns: Huh.
>> Question: (Inaudible) -- can you try and find that slide?
>> Martin Johns: I can do. I can try to find it. Yeah. So it takes integer value and translate it to characters and therefore --
>> Question: Doesn't that create quite a bit of JavaScript?
>> Martin Johns: It should. It does.
>> Question: Right. 100 characters equals a magnitude (inaudible).
>> Martin Johns: You can use -- so bloats up your code by 03, so -- because you can have separated the values here with the (inaudible) and so it's not that bad. And so your resulting HTML code gets bigger, but also our internet connections go (inaudible) --
>> Question: (Inaudible) --
>> Martin Johns: Yeah. I can look at that.
>> Question: Little less than (inaudible).
>> Martin Johns: Yeah. Security comes with a price.
>> Question: Yeah. I'm sure we have lots of bandwidth. Let's go for it.
>> Helen Wang: So Martin will be available tomorrow if you -- tomorrow morning if anybody wants to -- anybody who hasn't had -- Martin wants to talk anymore about things.
>>: Great. Thanks.
>>: Thanks.
>>: Thank you, Martin.
(applause)