 Hi, everyone, thanks to be here for this talk. I'm super happy there are so many people, because I will be talking about security. It's pretty boring. It's pretty old. It's not about performance, no G-Link, no microservice, no nothing fancy. But I believe it's very important anyway. I'm Nicolas Frankel. I've been doing consultancy as a developer for more than 15 years. And recently, I changed my life. And now I'm paid to go to conferences, which you should try if you don't do it. It's really fun. OK, well, since I assume everybody here is a Java developer, you probably know about the reflection API. So let me show you some code, because I like to do code. And it's not this one. It's this one up. So here, I've created a super simple class. And my class foo has a private attribute. And of course, you cannot access it in Java, right? No, nobody can access private field in Java, unless you can. Yes, so basically, where is the magic? Set accessible. Yeah, line 11, set accessible. Who never used that dirty trick? OK, so you know that. Ah, yeah, yeah, OK. Of course, of course. And let me show you something else, because that one is easy. But this one was shown to me by my friend Folker here. This one is a bit harder. So who can read that code? It's perhaps too small. I will try to get it a bit bigger. So I'm trying to do the same stuff. But once I get an attribute, I get the field. I get the field of the field. And I get the type field. So basically, you know that Java is a statically type language, right? So if I try to print this hidden stuff, it should give me a hint. It prints a string. Goodbye, type safety. Well, shit happens, right? Oh, not this one. Not this one again. I cannot find it. This one. OK, so this is reflection. And basically, with reflection, you can do a lot. And this tricks is done by a lot of languages. This reflection API is used by Groovy, is used by frameworks, just as Spring, is used by Hibernate, is basically used by any white spread language or framework on the TVM. So you cannot ignore that. You must cope with that. But actually, the TVM allows practically everything. You can make network calls. You can compile code on the fly. You can execute the same code on the fly. And perhaps it's not that a good idea. So what can we do to check that? The first logical step, A, we have static analyzers. We can check the code, whether it does something or not. Well, static analyzers are not that great right now. So they can check for very, very limited kind of pattern. Byte code analyzer go a bit further. But the problem is that you don't know what is allowed or not in your case. So basically, you must check the results every time. You can tell me that code review can check that stuff. Yes, they can, unless the code is reviewed only by one guy. And I mean, you are friends. And it doesn't want to disturb you too much. Never happens, right, of course. Security teams. Security teams can also be a great help in that. But with my experience, I have noticed there are two kinds of security teams. Is there anyone here working in security teams? I don't want to be offensive. No one? OK, so I can be a bit offensive. No, actually, there are two kind of security teams. They are the checkbox-oriented one. Like, you've got compliance. And then you follow a list of rules and you check them. I mean, whether it's the truth or not is not relevant. But you can prove that you did the checks because you have an Excel sheet. And of course, they don't help much. They are more like to hinder you or to be able to be audited. And the good one, the good one that really can tell you, here, you might have a security issue in that snippet of code. But unfortunately, because they are useful, well, they tend to be overused and they don't have time to help you with that. So you might be lucky once in a while, but in general, it's not possible. And perhaps you know about this little technique called steganography. That is very funny. Basically, you hide a message into another message. So you have a video file and you hide a picture in it. Or you have a picture and you hide text in it. Let me show you how it's done. So I have this picture of a cat. It's cute. It's harmless. What I will be doing, I will be hiding some code inside of it so I can have this stuff, say, good afternoon for them. I will hide something like X just to show you that it's done like that. I hide the code so I can show you the code. I'm using a steganographic class that I got on the internet. It's not very important. And then I can run the hidden code. And basically, these codes just wave the men.txt content into this harmless kitten. And you see, there is no difference between this harmless kitten and this harmless kitten. And now I can run the hidden codes and basically what I'm doing here is I'm reading the picture, extracting the codes, and compiling the class, and running the class on the fly. Pretty bad, right? It's not that great. And let me tell you about a simple process. Now what if I devised a library to read images? Useful one, someone that you would use in your day to day job. So I could advertise it, publish it on Maverin Central, and then I watched as everybody starts using it and nothing happens. But then I decide at one point in time to add steganographic features without telling anyone. And then because my project or your project or a friend's project is also committing pictures, then I could put some malicious codes and none would be the wiser, even with static analyzer, even with security teams checking your code. Because I mean, you might know what happened in the NPM ecosystem. That there was one very widespread library. I don't remember what it did, but basically at one point the guy who was behind the library said, oh, I don't want to care about it anymore. Who wants it? Then someone stepped in and that was fine. But the guy who replaced, at some point he added a bitcoin mining stuff inside the library. So you would just give him money with your CPU. Could do exactly the same here. Who is afraid now? Not that many people, only one, two, three, and not enough. So I have another demo to make you a bit more afraid. So here I've created a spring application. Sorry about that. And I have this application that basically just sends money over the wire. It's just a REST API, but basically it's pretty dead simple. I'm using this URL to transfer money from account one to another account with a certain amount. So if I run this stuff and I check the application here, it tells me, hey, you've transferred this amount of money. I can change the amount of money. And I send it to someone else. Sorry? OK, which number you want? OK, so yeah. I know with the attach API what I can do on a running GVM, I can change the bytecode that is running. Let me do it. So what I need to do, I just need to get the PID number. So this must be this one. I get the PID. This is my application, which basically is called act. Nothing happens. And now what I try to run that again, the GVM is still running. The bytecode has been changed on the fly. And the fun part, well, the fun depends for who, is that if I restart the application, I will stop it and re-run it. I don't have it anymore. Where is it? Here it is, yes. So basically, it's the original bytecode again. So I left no trace. I mean, for an attacker, I'm not a security person. But for an attacker, that's pretty powerful. You just do stuff and you leave no trace. Now who is afraid? A bit more people. That's good. But not yet enough, I believe. And there is a solution to that. I mean, there is a solution to that since ages. And that's why I'm telling you it's super old. That because if you remember, you had applets before, a long time ago. Remember applets? Yeah, we are all old people here. And basically, the applets were meant to run in a sandbox. Because we knew that running code from the internet, I mean, untrusted code was not a good idea to run on your machine. So basically, you're already at the sandbox. And the sandbox was provided by something called the security manager. Who knows about the security manager? Wow, a lot of people who uses the security manager. Wow, amazing. In general, I have no more than one guy. Here I have perhaps five. No, really, there are five times more. It's a lot. It's a lot. And basically, this security manager is based on the GDK. So basically, it checks the code inside of the GDK. Here, I will be very, very simple. I will just do it for a very simple policy file. So this is the structure of a policy file that you have a default policy file in the GDK. I advise you not to use the default one. I advise you to use your own one and then to add every permission. So basically, you are telling that for this drawer, you will grant this full permission with the full parameter and with the bar permission with parameter bar and bars. So very straightforward. So if you know about the security manager and you don't use it, why? It's work. Who said that? Yeah, yeah, that's a problem. It takes a very long time to do a good policy file, especially since you want to apply the list privilege principle in security. You want only to give the permissions that are enough to run the application. Like you don't see HMOD 777 just because it works. You just want to put the minimum amount of permissions. And it's a lot of work. And because of that, probably nobody does it. And I hope that I can give you a solution for that, a working solution. So a nice application here. I will stop this one. And I will use the Spring Pet Clinic. So basically, the Spring Pet Clinic is just an application that is based on Spring that I have a few screens. That is not a trivial application. It's a simple one. So I believe it's a good use case. So imagine we want to create a policy file for this stuff. So we start with a very simple policy file that I will remove yet. Just to show you how it would be done in the previous years. So you run it. You happen to stumble upon the first exception. And then you say, oh, what the exception? Java util proper permission. OK, I will add this one. Permission Java util permission and copy paste that. And now I think I'm not sure there must be a comma there or not. I don't remember. Yeah, another one. So each time I'm adding more permissions to get the minimum amount of permission that I need. Make sense to you? Yeah, no. It's not this one. It's because I missed a comma. Yeah, I'm never sure of the format. So yeah, this one is good. And now I can do the same. I have the permission. And here it needs a right. So I can write like that. Or I can write like that. And because I think it's better like that, I do it like that. And set factory. How much time do you still have left? Some hours, right? Yeah, I mean you still want to finish the file, right? So the final file, and I took some shortcuts. And I took shortcuts, really. I took some shortcuts which basically doesn't make the least minimum privilege file. So that's the problem. And if you do it step by step like that, it's going to take a long time for any non-trivial application. And another issue that every time you change your code, you cannot just add permission because perhaps you don't need that many permissions anymore. So you need to start from scratch. And of course, if you change your framework or even upgrade a version of a dependency, guess what? You need to start from scratch again. So it's not that fun. However, there is a way to do that. What we can do is we can have this settings. So I add the security manager. I set the security policy here. Just a comment. There are two equal signs because I don't want to add permission to the default set of permissions. I want to replace every permission. So because if the initial set of permissions is compromised, then I want to be safe again that. And what I can do is I can debug every access. So every time the security manager is checked for a permission, I can log it. There are duplicates. That's be cool. That's good enough. And now I've started the application. I didn't run it yet. If I run it, I have another set of permissions that will be requested. And so basically what I can do with that log, I can devise an automated process that takes this log file and creates a policy file out of that. I can remove the duplicates file. I can do a lot of stuff. Normally, so this is something that I didn't mention is basically there is a permission called All Permission. And that's what I used. Yeah, it seems pretty stupid, actually, to have a permission saying every permission possible. But with logging, it's actually usable to create a policy file with it. So it's very interesting. And now with my final policy, I'm able not only to run the application. And now I've disabled the logging for permissions. So basically, it starts pretty well. And it runs as well. How long do I still have? Five minutes. OK. Yeah, 25 minutes is not a lot for that. So now it's time to choose. You might forget that what I told you during this session, everything is fine. You will get back to work, nothing will happen. But perhaps the guys or the woman next to you heard it and will create a library to read pictures might happen. Now, to be more serious, now it's your choice. The problem is that it shouldn't be a default choice. It's called risk mitigation. You should be aware of the risk and assess the risk and decide whether it's cost effective to create a policy file for your application or not. But remember that if you don't do it, you can do a lot of crap with the GVM because you can do everything. And since some of you told me they were afraid, I hope at least you will check because it's a huge security risk. And I cannot understand why everything now is secure but not the GVM. So thanks for your attention. You can read my blog, follow me on Twitter. There are sources for the code that I showed you, both the hoop stuff and the Spring Pet Clinic with the policy file. And also I wrote like an article that details much deeper about securing the GVM because you can also sign yours and blah, blah, blah. So we have like four minutes for questions. Any question? One question, yes. So the question is, if I grant all permission, does it defeat the purpose? Of course it defeats the purpose. My point was to use all permission only in conjunction with logging so I could create my policy file, the real one. Does that answer your question? OK. Other question, yes, another question. Does it mean that you need 100% coverage? Sorry, I will need the mic. Sorry about that. At my age, you know. It's not what it used to be. Does it mean that you need 100% coverage to be sure to have all the logings? That's a very good question. Of course you need to cover every screen or features in your application. But I guess you already have it, right? Is it possible to apply it only for the libraries you have? Sorry? Is it possible to apply the policy only for the libraries you have identified as external? No. No, at some point I was thinking perhaps every library could provide its own policy file. But the problem is if you are using a single feature of your library, then the policy file is again too much. And it's not the least minimum privileged policy. So you have to do it on the end, in the end of the process. Yes, you. Sorry? And now actually, that's a very good question. The question is how readable or viewable is this file? OK, what's the alternative? The alternative is to read the entire application, not understanding what it does, because you are too close. If we have a bit of understanding of the syntax of this file, it's pretty readable, and then you can compare with what the application is supposed to do. And then if it tells you, yeah, I need to use reflection, you are using spring, that's fine, because you know that spring uses reflection. If you say, I want to connect to port x, y, z, then you might say, mm, y.