I'm a little confused about CVE-2022-22950 and the corresponding Spring advisory. The latter says that the vulnerability can be exploited through:
[...] specially crafted SpEL expression [...]
However, an application that allows users to craft SpEL expressions, allows these users to do pretty much anything. Including code injection, which has full impact on confidentiality, integrity, and availability. Plenty of other DoS opportunities here. Take this SpEL snippet for example, which executes the pwd command:
T(java.lang.Runtime).getRuntime().exec("pwd")
This command is fairly harmless, but it could be substituted with anything! Now, SpEL supports different EvaluationContexts which can be used to restrict what is allowed in a SpEL expression. E.g. the SimpleEvaluationContext forbids type expressions, like the one in the above SpEL snippet.
This leads me to 2 sets of questions:
Is CVE-2022-22950 even relevant for applications that use an unrestricted EvaluationContext for tainted SpEL expressions?
E.g. applications that trust selected users (like admins) enough to allow them executing arbitrary code? Or, ideally, have additional sand-boxing measures in place?
It seems that in such scenarios (questionable as they may be) this DoS vulnerability does not add anything new to the game. Would it make sense to improve the security advisory and warn against processing user-controlled SpEL code in a permissive EvaluationContext?
Does CVE-2022-22950 really require a "specially crafted SpEL expression"?
Or could an attacker exploit this DoS vulnerability by crafting data that will be processed by an otherwise harmless SpEL expression? E.g. sending a long list of query parameters to a web application that processes them using a hard-coded SpEL expression?
When I look at the code changes it seems that crafting the data might be enough? If so, the wording of the security advisory should be adjusted!
Looking at the original advisory (translated from Chinese) - https://4ra1n.love/post/Xrym_ZDj3/
It looks like exploiting this does require evaluation of arbitrary SpEL expressions. However - it allows for DoS even when using the SimpleEvaluationContext which is normally considered safe (or at least safer than EvaluationContext) and for example doesn't allow for RCE even when evaluating an arbitrary expression. But with this vulnerability, it will allow for a DoS.
The vulnerable code shown in the advisory -
SpelExpressionParser parser = new SpelExpressionParser();
Expression expr = parser.parseExpression("new int[1024*1024*1024][2]");
SimpleEvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
expr.getValue(context);
Related
The unicode package in Go provides functions such as unicode.IsDigit and unicode.IsUpper. Are these safe to use for form input validation, password validation in particular?
How would you approach form validation in Go without using a third party package? From what I can gather regex is expensive and should be avoided if possible, is this a viable solution?
Here's an example using the unicode package:
https://play.golang.org/p/6XLSqPim54E
I wouldn't say that regex is expensive and should be avoided if possible. It is the best tool for your case. Although there is nothing wrong to use unicode package for password validation, it might be more readable for other programmers to just use single regexp, where you can write all your password requirements into a single regular expression.
Ad regex performance:
You can read about golang regex implementation's performance here. I wouldn't care about it unless you're implementing a very critical performance heavy tool where you can especially measure that regex slows your program down.
I've got a config .cfg file that has the hostname hard coded in it. I'm trying to find a way for the hostname to be gotten locally (dynamically) by running a command similar to hostname -f to have it configure the variable in the .cfg, without running a script, like python, to write the config file ahead time. Is it possible to run a 'yum' command that gets the hostname to use in the YAML/yml file?
Thanks to Wikipedia, I think I found out why no one is helping me with this:
Wiki YAML -> Security
Security
YAML is purely a data representation language and thus has no executable commands. While validation and safe parsing is inherently possible in any data language, implementation is such a notorious pitfall that YAML's lack of an associated command language may be a relative security benefit.
However, YAML allows language-specific tags so that arbitrary local objects can be created by a parser that supports those tags. Any YAML parser that allows sophisticated object instantiation to be executed opens the potential for an injection attack. Perl parsers that allow loading of objects of arbitrary class create so-called "blessed" values. Using these values may trigger unexpected behavior, e.g. if the class uses overloaded operators. This may lead to execution of arbitrary Perl code.
The situation is similar for Python or Ruby parsers. According to the PyYAML documentation
I'm building a DSL that uses names for procedures (essentially) that must be unique.
It's unclear what sort of error term to use to represent a second definition.
existence_error sorta kinda fits, but I'm uncomfortable with it. It seems to imply missing definition, not multiple definition.
permission_error(modify, procedure, Name/Arity) seems promising, but seems to imply "some people could do this, but not you". Without further enlightenment, I'll use this.
syntax_error sorta kinda fits, but is defined as being for read_term only.
Should I define my own here? The spec says 'use these when you can'.
In the old times there was no SWISH or Pengines where a Prolog prozessor was used by multiple users, and probably through batch processing there wasn't much awareness that resources could be blocked by other users. So the explanation of the error term permission_error/3 is mostlikely as SICStus Prolog describes it here:
"A permission error occurs when an operation is attempted that is
among the kinds of operation that the system is in general capable of
performing, and among the kinds that you are in general allowed to
request, but this particular time it isn't permitted."
http://sicstus.sics.se/sicstus/docs/4.0.4/html/sicstus/ref_002dere_002derr_002dper.html
But I agree, from the name of the error term, we would expect its application range only some violation of access or modification rules, and not some semantic restrictions over syntactic structure such as a DSL.
But you are probably not the only one that has these problems. If your Prolog system has a messaging subsystem, where you can easily associate error terms with user friendly text, I don't see any reasons to not introduce new error terms.
You could adopt the follow error terms already suggested by SICStus Prolog and not found in the ISO core standard:
"A consistency error occurs when two otherwise valid values or
operations have been specified that are inconsistent with each other."
http://sicstus.sics.se/sicstus/docs/4.0.4/html/sicstus/ref_002dere_002derr_002dcns.html
"A context error occurs when a goal or declaration appears in the wrong
place. There may or may not be anything wrong with the goal or
declaration as such; the point is that it is out of place."
http://sicstus.sics.se/sicstus/docs/4.0.4/html/sicstus/ref_002dere_002derr_002dcon.html
Especially SWI-Prolog has such a messaging subsystem and SWI-Prolog has long said good-bye to interoperability with other Prolog systems. So the only danger if you would use SWI-Prologs messaging is a certain lock-in, which might not bother you.
I am aware that by default Java does not have the so-called eval (what I pronounce as "evil") method. This sounds like a bad thing—knowing you do not have something which so many others do. But even worse seems being notified that you can't have it.
My question is: What is solid reasoning behind it? I mean, Google'ing this just returns a massive amount of old data and bogus reasons—even if there is an answer that I'm looking for, I can't filter it from people who are just throwing generic tag-words around.
I'm not interested in answers that are telling me how to get around that; I can do that myself:
Using Bean Scripting Framework (BSF)
File sample.py (in py folder) contents:
def factorial(n):
return reduce(lambda x, y:x * y, range(1, n + 1))
And Java code:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("jython");
engine.eval(new FileReader("py" + java.io.File.separator + "sample.py"));
System.out.println(engine.eval("factorial(932)"));
Using designed bridges like JLink
This is equivalent to:
String expr = "N[Integrate[E^(2 y^5)/(2 x^3), {x, 4, 7}, {y, 2, 3}]]";
System.out.println(MM.Eval(expr));
//Output: 1.5187560850359461*^206 + 4.2210685420287355*^190*I
Other methods
Using Dijkstras shunting-yard algorithm or alike and writing an expression evaluator from scratch.
Using complex regex and string manipulations with delegates and HashMultimaps.
Using Java Expressions Library
Using Java Expression Language
Using JRE compliant scripting language like BeanShell.
Using the Java Assembler and approach below or direct bytecode manipulation like Javaassist.
Using the Java Compiler API and reflections.
Using Runtime.getRuntime().exec as root
"eval" is only available in scripting languages, because it uses the same interpreter that runs the rest of the code; in such languages the feature is free and well integrated, as in scripting environment it makes little difference if you run a string or a "real" function.
In copiled languages, adding "eval" would mean bundling the whole compiler - which would defy the purpose of compiling. No compiled language I know (even dynamic ones, like ActionScrip3) has eval.
Incidentally, the easiest way to eval in Java is the one you forgot to mention: JRE 1.6 comes with Javascript engine, so you can eval any Javascript in two lines of code. You could even argue that the presuposition of your question is false. Java 1.6 bundles a very advanced expression evaluator.
As Daniel points out there is at least one limitation that eval-solutions face in java. The php eval for example executes the code as if it was part of the surrounding method with complete access to local variables, this is not possible to do in standard java. Without this feature eval alternatives require a lot more work and verbosity, which makes them a lot less attractive for "quick" and "easy" solutions.
eval() is mostly part of interpreted languages where the names of local variables and code structure(scopes) are available at runtime, making it possible to "insert" new code. Java bytecode no longer contains this information leaving eval() alternatives unable to map access to local variables. (Note: I ignore debug information as no program should rely on it and it may not be present)
An example
int i = 0;
eval("i = 1");
System.out.println(i);
required pseudocode for java
context.put("i",new Integer(0));
eval(context,"i = 1");
System.out.println(context.get("i"));
This looks nice for one variable used in the eval, try it for 10 in a longer method and you get 20 additional lines for variable access and the one or other runtime error if you forget one.
Because evaluation of arbitrary Java expressions depends on the context of it, of variable scopes etc.
If you need some kind of variable expression, just use the scripting framework, and badamm! you have lots of different kinds of expression evaluation. Just take one kind like JavaScript as a default, and there is your eval()!
Enterprisy as Java is, you are not constrained to one choice.
But even worse seems being notified that you can't have it.
I think you are misunderstanding what (most of) those articles are saying. Clearly, there are many ways to do expression evaluation in a Java application. They haven't always been available, but at least some of them have been around for a long time.
I think what people are trying to say is that expression evaluation is not available as native (i.e. as an intrinsic part of Java or the standard libraries) and is unlikely to be added for a number of good reasons. For example:
Native eval would have significant security issues if used in the wrong place. (And it does for other languages; e.g. you shouldn't use eval in Javascript to read JSON because it can be a route for injecting bad stuff into the user's browser.)
Native eval would have significant performance issues, compared with compiled Java code. We are talking of 100 to 10,000 times slower, depending on the implementation techniques and the amount of caching of "compiled" eval expressions.
Native eval would introduce a whole stack of reliability issues ... much as overuse / misuse of type casting and reflection to.
Native eval is "not Java". Java is designed to be a primarily static programming language.
and of course ...
There are other ways to do this, including all of the implementation approaches that you listed. The Java SE platform is not in the business of providing every possible library that anyone could possibly want. (JRE downloads are big enough already.)
For these reasons, and probably others as well, the Java language designers have decided not to support expression evaluation natively in Java SE. (Even so, some expression support has officially made it into Java EE; e.g. in the form of JSP Expression Language. The classes are in the javax.el package ... or javax.servlet.jsp.el for an older / deprecated version.)
I think you already put the solution to your answer - bundle the BeanShell jar with your application (or lobby for it to be included in the JRE sometime), and you have your Java expression evaluator. It will still need a Binding of the input variables, though.
(What I'm more curious about: How does sandboxing of such a script/expression work? I don't want my web users to execute dangerous code in my server.)
I'm working on a project which will do some complicated analyzing on some user-supplied input. There will be 3 parts of the code:
1) Input supplied by user, such as keywords
2) Rules, such as if keyword 1 is repeated 3 times in keyword 5, do this, etc.
3) And the analyzing itself which executes the rules and processes the user input, and generates the output necessary based on the processing.
Naturally this will lead to a lot of spaghetti code and many, many if statements in the processing code. I want to avoid that, and keep the rules (i.e. the if statements) separately from the code which loops through the user input and generates the output.
How can I do that, i.e. what is the best way?
If you have enough rules that you want to externalize, you could try using a business rules engines, like Drools in Java.
A business rules engine is a software system that executes one or more business rules in a runtime production environment. The rules might come from legal regulation ("An employee can be fired for any reason or no reason but not for an illegal reason"), company policy ("All customers that spend more than $100 at one time will receive a 10% discount"), or other sources. (Wikipedia)
It could be a little bit overhead depending of what you're trying to do. In my company we're using such kind of tools for our quality analysis tool.
Store it in XML. Easy to parse and update.
I had designed a code generator, which can be controllable from a xml file.
For each command I had a entry in the xml. I was processing the node to generate the opcode for that command. Node itself contains the actions I need to do for getting the opcode. For some commands I had to look into database, all those things I had put in this xml file.
Well, i doubt that it is necessary to have hughe if statements if polymorphism is applied correctly.
Actually, you need a proper domain model for your rules. This goes somehow into the direction of the command pattern, depending on the complexitiy of your code maybe in combination with the state machine pattern.
Once you have your model, defining rules is instantiate them correctly.
This could be done by having an xml definition, which is parsed and transformed into your model. But the new modern and even more fancy way would be using DSLs. If you program in Java and have a certain freedom about your libraries, this would be a proper use case for Embedded DSLs with Groovy. Basically you would need a Builder which constructs your model, that's all.
You always can implement factory that will create certain strategies according to passed parameters. And then you will use those strategies in your code without any if.
If it's just detecting keywords, a finite state machine or similar. If it's doing more, then other pattern matching systems, such as rules engines.
Adding an embedded scripting language to your application might help. The rules would then be expressed in scripts, executed by the applications on processing.
The idea is that scripts are easy to change and contain high level logic that will be executed by your application in details.
There are a lot of scripting languages available to do this : lua, Python, Falcon, squirrel, angelscript, etc.
Have a look at rule engines!
The approach from Lars may also be arguable.