Perfect way to configure esapi to mitigate XSS SQLI {GET/POST data} - java

We have a jaxrs service, Unfortunately the raw query is executed,No prepared statement. We used ESAPI to mitigate XSS,SQLI. Something like below:
private String mitigateSQLI(String value) {
Encoder instance = ESAPI.encoder();
Codec c = new MySQLCodec(MySQLCodec.Mode.ANSI);
return instance.encodeForSQL(c, value);
}
private String mitigateXSS(String value) {
if (value == null)
return null;
// Use the ESAPI library to avoid encoded attacks.
value = ESAPI.encoder().canonicalize(value);
// Avoid null characters
value = value.replaceAll("\0", "");
// Clean out HTML
Document.OutputSettings outputSettings = new Document.OutputSettings();
outputSettings.escapeMode(EscapeMode.xhtml);
outputSettings.prettyPrint(false);
value = Jsoup.clean(value, "", Whitelist.none(), outputSettings);
return value;
}
Along with the ESAPI.properties file with default configuration.
Still we are facing SQLI on certain scenarios, Knowing the queries are concatenated and formed.
Wanted to know if the best way/configuration to mitigate these things. Way can be the ESAPI properties or these ESAPI available methods.

Don't run away to the alternatives. As quoted in bold in the OWASP
Primary Defenses:
Option 1: Use of Prepared Statements (with Parameterized Queries)
Option 2: Use of Stored Procedures
Option 3: Whitelist Input Validation
Option 4: Escaping All User Supplied Input
Additional Defenses:
Also: Enforcing Least Privilege
Also: Performing Whitelist Input Validation as a Secondary Defense
Configuring ESAPI.properties as per application requirement is important. When not using Prepared Statement, You must escape inputs on the server side. For Java , StringEscapeUtils from Apache does the job.

It's important to note that the design intent for ESAPI's SQLi codecs was to provide emergency support in a post-compromise scenario to buy time for you to rewrite the vulnerable queries with a PreparedStatement or some equivalent. OWASP makes no assurance because the peculiar language quirks present in the various RDBMS implementations aren't typically common knowledge. It's not that ESAPI won't protect you at all--but it will never be as good as with a PreparedStatement. I would expect only a partial mitigation.
I would also recommend against using Jsoup in lieu of Validator.getValidSafeHTML(). Jsoup will attempt to "correct" invalid HTML, and that gets complicated extremely quickly in the contexts of input validation and safe HTML.

Related

Refactor this code to not place tainted, user-controlled data in the header

I'm trying to add custom header in my HTTPHeader like below
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
if (headerName.equalsIgnoreCase("SampleHeader"){
headers.add(headerName, request.getHeader(headerName));
}
}
but I'm getting below bug while running sonar.
"Refactor this code to not place tainted, user-controlled data in the header."
I think adding a regex might solve my problem, but I had two problems.
I'm need to write an regex that allow alphabets, number and . , ! - _ But I'm unable to create one.
I'm not sure checking using some regex will debinately solve my problem.
You can use OWASP Encoder to encode user input:
<dependency>
<groupId>org.owasp.encoder</groupId>
<artifactId>encoder</artifactId>
<version>1.2.3</version>
</dependency>
Add Encode.forJava(userInput) for user input which will:
Encodes for a Java string. This method will use "\b", "\t", "\r",
"\f", "\n", """, "'", "\", octal and unicode escapes. Valid
surrogate pairing is not checked. The caller must provide the
enclosing quotation characters. This method is useful for when writing
code generators and outputting debug messages.
So in your case it may be:
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = Encode.forJava(headerNames.nextElement());
if (headerName.equalsIgnoreCase("SampleHeader"){
headers.add(headerName, request.getHeader(headerName));
}
}
The problem is because you are using a header name ("SampleHeader") to make a logical decision in your code.
User provided data, such as URL parameters, POST data payloads or cookies, should always be considered untrusted and tainted. Applications logging tainted data could enable an attacker to inject characters that would break the log file pattern. This could be used to block monitors and SIEM (Security Information and Event Management) systems from detecting other malicious events.
In this case if I wanted to fool your program into adding a new header into the headers list I would simply need to send a curl like this:
curl -X GET http://localhost/your/path --header 'SampleHeader: someValue'
This problem could be mitigated by sanitizing the user provided data before logging it.
What SonarQube is trying to tell you is that you are exposing your logic to input from the clients. A better solution would be to refactor your code to not depend on a specific header from the client to perform some action. Its hard to suggest sample code without seeing a little more of the codebase.
Hope this helps!

Trying to replace part of a string starts with /x2D

In JMeter, I used a Regular Expression Extractor to extract part of an HTML response. I then passed that to a BeanShell Post Processor. However, having trouble replacing \x2D to -. Is there a way to do this or perhaps do I need to extract the response as
String yourvar = vars.get("accessToken");
String anotherVar = yourvar.replace("data.access_token = '","");
String finalAccessToken = anotherVar.replace("\x2D","-");
vars.put("finalAccessToken",finalAccessToken);
It is not liking the "\x2D" part. It works if I find \x2D but the original string only has .
You need to escape your target String parameter.
final String finalAccessToken = anotherVar.replace("\\x2D", "-");
If it's not what you're asking for, add more info to the question. That's all what I was able to understand.
It is recommended to use JMeter's built-in test elements where possible. In particular your case you might be interested in __strReplace() custom JMeter Function
Install Custom JMeter Functions bundle using JMeter Plugins Manager
Use the following expression to make the replacement:
${__strReplace(${anotherVar},\\\x2D,-,)}
If you want to go for scripting - make sure to use JSR223 PostProcessor and Groovy language. Be aware that you will still need to escape backslash with another backslash like:
String finalAccessToken = anotherVar.replace("\\x2D","-");

How to detect XSS in Java using OWASP

I have this thing which I'm dealing with right now, XSS.
I need to detect if a string contains XSS or not. In order to solve it I used that link. And this is the code I'm using:
public static boolean containsXSS(String value) {
if (StringUtils.isEmpty(value)) {
return false;
}
String stripXss = stripXSS(value);
return !value.equals(stripXss);
}
public static String stripXSS(String value) {
if (StringUtils.isBlank(value))
return value;
// Use the ESAPI library to avoid encoded attacks.
Encoder encoder = ESAPI.encoder();
value = encoder.canonicalize(value);
// Avoid null characters
value = value.replaceAll("\0", "");
// Clean out HTML
Document.OutputSettings outputSettings = new Document.OutputSettings();
outputSettings.escapeMode(Entities.EscapeMode.xhtml);
outputSettings.prettyPrint(false);
value = Jsoup.clean(value, "", Whitelist.none(), outputSettings);
return value;
}
Using the code above I do succeed to catch things like: <script>alert('xss')</script>
My problem is that I identify the following string as containing XSS although it's not:
{"item" :5}
It's because jsoup.clean turns it into {"item" :5}
I have tried to solve but with no success.
It makes me wonder if my algorithm is completely wrong (if so where can I find the algorithm to detect XSS), perhaps I don't need to compare to the original String?
I would very appreciate if you could help me.
thanks
You cannot detect if a string contains XSS. XSS in an output issue, not an input issue. Data benign in one context, can cause malicious behaviour in another.
Validate data using white lists to ensure data is valid in your domain (numbers are numbers, names do not contain unwantef characters etc.). This will stop some but definitely not all attacks.
Contextually encode user provided output as explained in the OWASP XSS prevention cheat sheet
Dont mix client side and server side templates
Be careful when using unsanitized data in javascript (see DOM-based XSS)

How match JAXB elements in CIM/RDF?

Trying to load a model from a CIM/XML file acording to IEC 61970 (Common Information Model, for power systems models), I found a problem;
According JAXB´s graphs between elements are provided by #XmlREF #XmlID and these both should be equals to match. But in CIM/RDF the references to a resource through an ID, i.e. rdf:resource="#_37C0E103000D40CD812C47572C31C0AD" contain the "#" character, consequently JAXB is unable to match "GeographicalRegion" vs. "SubGeographicalRegion.Region" when in the rdf:resource atribute the "#" character is present.
Here an example:
<cim:GeographicalRegion rdf:ID="_37C0E103000D40CD812C47572C31C0AD">
<cim:IdentifiedObject.name>GeoRegion</cim:IdentifiedObject.name>
<cim:IdentifiedObject.localName>OpenCIM3bus</cim:IdentifiedObject.localName>
</cim:GeographicalRegion>
<cim:SubGeographicalRegion rdf:ID="_ID_SubGeographicalRegion">
<cim:IdentifiedObject.name>SubRegion</cim:IdentifiedObject.name>
<cim:IdentifiedObject.localName>SubRegion</cim:IdentifiedObject.localName>
<cim:SubGeographicalRegion.Region rdf:resource="#_37C0E103000D40CD812C47572C31C0AD"/>
</cim:SubGeographicalRegion>
I realize you're asking for a solution using JAXB, but I would urge you to consider an RDF-based solution as it is more flexible and robust. You're basically trying to reinvent what RDF parsers already have built in. RDF/XML is a difficult format to parse, it doesn't make much sense to try and hack your own parsing together - especially since files that have very different XML structures can express exactly the same information: this only becomes apparent when looking at the level of the RDF. You may find that your JAXB parser workaround works on one CIM/RDF file but completely fails on another.
So, here's an example of how to process your file using the Sesame RDF API. No inferencing is involved, this just parses the file and puts it in an in-memory RDF model, which you can then manipulate and query from any angle.
Assuming the root element of your CIM file looks something like this:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:cim="http://example.org/cim/">
(only a guess of course, but I need prefixes for a proper example)
Then you can do the following, using Sesame's Rio RDF/XML parser:
String baseURI = "http://example.org/my/file";
FileInputStream in = new FileInputStream("/path/to/my/cim.rdf");
Model model = Rio.parse(in, baseURI, RDFFormat.RDFXML);
This creates an in-memory RDF model of your document. You can then simply filter-query over that. For example, to print out the properties of all resources that have _37C0E103000D40CD812C47572C31C0AD as their SubGeographicalRegion.Region:
String CIM_NS = "http://example.org/cim/";
ValueFactory vf = ValueFactoryImpl.getInstance();
URI subRegion = vf.createURI(CIM_NS, "SubGeographicalRegion.Region");
URI res = vf.createURI("http://example.org/my/file#_37C0E103000D40CD812C47572C31C0AD");
Set<Resource> subs = model.filter(null, subRegion, res).subjects();
for (Resource sub: subs) {
System.out.println("resource: " + sub + " has the following properties: ");
for (URI prop: model.filter(sub, null, null).predicates()) {
System.out.println(prop + ": " + model.filter(sub, prop, null).objectValue());
}
}
Of course at this point you can also choose to convert the model to some other syntax format for further handling by your application - as you see fit. The point is that the difference between the identifiers with the leading # and without has been resolved for you by the RDF/XML parser.
This is of course personal opinion only, since I don't know the details of your use case, but I think you'll find that this is quite quick and flexible. I should also point out that although the above solution keeps the entire model in memory, you can easily adapt this to a more streaming (and therefore less memory-intensive) approach if you find your files are too big.

Jena - how to use ontology + rdf together

I have a RDF file that I am able to read using
Model model = ModelFactory.createDefaultModel();
// use the FileManager to find the input file
InputStream in = FileManager.get().open(args[0]);
if (in == null) {
throw new IllegalArgumentException(
"File: " + args[0] + " not found");
}
// read the RDF/XML file
model.read(in, null);
I also have OWL file which contains the description of the ontology which is used for creating my models. My question is: do I need to read this file (and how?) in order to work with my RDF model correctly?
To make myself clear, I will give ou an example:
I need to know whether one resource has some relationship with other resource (for example Station1 has predicate "isResponsibleFor" Workorder1). How can I do this with Jena?
If I try to use something like resource.hasProperty(ResourceFactory.createProperty("isResponsibleFor")), it returns false (but the property is there!).
Can you direct me to some advanced tutorial on this topic perhaps? I found many tutorials on Papache site etc. but they do not provide me with the information I am looking for. Sorry if the question is not clear, I am quite new to Jena
EDIT: currently, I am searching whether my model contains given statement using this:
public static boolean containsStatement(Model model, String sub,
String pred, String obj) {
// list the statements in the Model
StmtIterator iter = model.listStatements();
// print out the predicate, subject and object of each statement
while (iter.hasNext()) {
Statement stmt = iter.nextStatement(); // get next statement
Resource subject = stmt.getSubject(); // get the subject
Property predicate = stmt.getPredicate(); // get the predicate
RDFNode object = stmt.getObject(); // get the object
if (subject.toString().contains(sub)
&& predicate.toString().contains(pred)
&& object.toString().contains(obj)) {
return true;
}
}
return false;
}
but I am pretty sure that this is highly ineffective approach.. could you suggest me something more elegant and fast? Thanks!
Short answer: no, you don't need the ontology to work with your RDF file, but in many cases it can help your application.
First, you can shorten loading your file:
Model model = FileManager.get().loadModel( args[0] );
Now, in order to work with the relationship between resources, as given by the URI of the property connecting the subject resource to the object, you need the full URI of the predicate. Typically, this will be something like http://example.com/foo#isResponsibleFor. If you just use the short-name of predicate, it won't work - which is what you are finding.
You don't show any examples of your actual RDF data, so I'm going to use a fake namespace. Use your actual namespace in your code. In the meantime:
String NS = "http://example.com/example#";
Property isResponsibleFor = model.getProperty( NS + "isResponsibleFor" );
Resource station = model.getResource( NS + "station1" );
for (StmtIterator i = station.listProperties( isResponsibleFor ); i.hasNext(); ) {
Statement s = i.next();
Resource workorder = s.getResource();
// now you can do something with the work-order resource
}
In your code, you had:
public static boolean containsStatement(Model model, String sub, String pred, String obj)
There are a number of things wrong here. First, it's better if you can write your code in a more object-oriented style, which tends not to use static methods if that can be avoided. Second, don't use strings when you refer to things in a model. Jena has the Resource class to denote resources in a model, and many other RDF-specific classes as well. Use strings for handling input from your user, otherwise convert strings to resources or other RDF objects as soon as you can. Thirdly, I'd advise against exposing the details of your representation via your object's API. containsStatement makes it clear in the API that you are using RDF triples; that's not a detail that callers of the API need to know and it breaks encapsulation. A better API would have methods such as listWorkItems - that relates to the domain, and hides details of the implementation.
Regarding the use of your ontology, there are two specific ways your application can benefit from using your ontology. First, you can automatically generate statements such as:
Property isResponsibleFor = model.getProperty( NS + "isResponsibleFor" );
by using Jena's schemagen vocabulary generator tool. You can use schemagen as part of your build process to ensure that your vocabulary class automatically stays up-to-date as your ontology changes.
Secondly, by using Jena's inference engines, you can use the ontology to infer additional statements about your domain. For example, suppose you have class WidgetOrder, which is a type of WorkItem. Without inference, and without your ontology, if you ask the model object to list all of the WorkItems, it won't list the WidgetOrder resources. However, with the ontology and the reasoner, listing resources of type WorkItem will also return the resources that only have a declared type of WidgetOrder, because the other types can be inferred.

Categories