Say I want to maliciously call a function which is already defined, myfunc().
How could I achieve xss attack bypassing double quote and angle brackets escaping?
<h2>Profile of INPUTNAME</h2><p>INPUT2</p>Homepage
(The upper case fields are user inputs)
How could I call myfunc() without adding the script tags around it?
(Un)fortunately it appears that XSS won't be possible in this instance.
If angle brackets and double quote characters are escaped, this is enough to prevent XSS in HTML body and double quoted entity value contexts.
Technically under the XSS Experimental Minimal Encoding Rules for HTML body, the & character should be encoded too, but I can't see a way here to use that to the attacker's advantage either in the HTML body or within the entity value.
The only exception to this is if the character set was specified as UTF-7 (or as the attacker you could change it to such) then you could use the following attack:
INPUTNAME = +ADw-script+AD4-myfunc()+ADw-/script+AD4-
this would be rendered as
<h2>Profile of <script>myfunc()</script></h2><p>INPUT2</p>Homepage
You can try these injections
INPUTNAME=<img src=X onerror=myfunc>
INPUTURL="><img src=X onerror=myfunc>
which will try to call the myfunc javascript function since it will fail to load the image named X
Try this injection: <a href="javascript:myFunc();">;
when someone clicks on the link, the code gets run.
If you want to pass string parameters, use slashes (like /string/ vs "string")
Related
I'm working on a simple localization function for my scripts and, although it's starting to work quite well so far, I don't know how to avoid scape/special characters to be shown in UI as part of the text after feeding the widgets with the strings returned by f:read().
For example, if in a certain Strings.ES.txt's line I have: Ignorar \"Etiquetas de capa\", I'd expect backslashes didn't end showing up just like when I feed the widget with a normal string between doble quotes like: "Ignorar \"Etiquetas de capa\"", or at least have a way to avoid it. I've been trial-and-erroring with tostring() and load() functions and different (surely nonsense 🙄) concatenations like: load(tostring("[[" .. f:read()" .. ]]")) and such without any success, so here I'm again...
Do someone know if there is a way to get scape characters in a string returned by f:read() still behave as special as when they are found in a regular one?
I don't know how to avoid [e]scape/special characters to be shown in UI as part of the text
What you want is to "unescape" or "unquote" a string to interpret escape sequences as if it were parsed as a quoted string by Lua.
[...] with the strings returned by f:read() [...]
The fact that this string was obtained using f:read() can be ignored; all that matters is that it is a string literal without quotes using quoted string escapes.
I've been trial-and-erroring with tostring() and load() functions and different [...] concatenations like: load(tostring("[[" .. f:read()" .. ]]")) and such without any success [...]
This is almost how to do it, except you chose the wrong string literal type: "Long" strings using pairs square brackets ([ and ]) do not interpret escape sequences at all; they are intended for including long, raw, possibly multiline strings in Lua programs and often come in handy when you need to represent literal strings with backslashes (e.g. regular expressions - not to be confused with Lua patterns, which use % for escapes, and lack the basic alternation operator of regular expressions).
If you instead use single or double quotes to wrap the string, it will work fine:
local function unescape_string(escaped)
return assert(load(('return "%s"'):format(escaped)))()
end
this will produce a tiny Lua program (a "chunk") for each string, which just consists of return "<contents>". Recall that Lua chunks are just functions. Thus you can simply call the function to obtain the value of the string it returns. That way, Lua will interpret the escape sequences for us. The same approach is often used to use Lua for reading data serialized as Lua code.
Note also the use of assert for error handling: load returns nil, err if there is a syntax error. To deal with this gracefully, we can wrap the call to load in assert: assert returns its first argument (the chunk returned by load) if it is truthy; otherwise, if it is falsy (e.g. nil in this case), assert errors, using its second argument as an error message. If you omit the assert and your input causes a syntax error, you will instead get a cryptic "attempt to call a nil value" error.
You probably want to do additional validation, especially if these escaped strings are user-provided - otherwise a malicious string like str"; os.execute("...") can trivially invoke a remote code execution (RCE) vulnerability, allowing it to both execute Lua e.g. to block (while 1 do end), slow down or hijack your application, as well as shell commands using os.execute. To guard against this, searching for an unescaped closing quote should be sufficient (syntax errors e.g. through invalid escapes will still be possible, but RCE should not be possible excepting Lua interpreter bugs):
local function unescape_string(escaped)
-- match start & end of sequences of zero or more backslashes followed by a double quote
for from, to in escaped:gmatch'()\\*()"' do
-- number of preceding backslashes must be odd for the double quote to be escaped
assert((to - from) % 2 ~= 0, "unescaped double quote")
end
return assert(load(('return "%s"'):format(escaped)))()
end
Alternatively, a more robust (but also more complex) and presumably more efficient way of unescaping this would be to manually implement escape sequences through string.gsub; that way you get full control, which is more suitable for user-provided input:
-- Single-character backslash escapes of Lua 5.1 according to the reference manual: https://www.lua.org/manual/5.1/manual.html#2.1
local escapes = {a = '\a', b = '\b', f = '\b', n = '\n', r = '\r', t = '\t', v = '\v', ['\\'] = '\\', ["'"] = "'", ['"'] = '"'}
local function unescape_string(escaped)
return escaped:gsub("\\(.)", escapes)
end
you may implement escapes here as you see fit; for example, this misses decimal escapes, which could easily be implemented as escaped:gsub("\\(%d%d?%d?)", string.char) (this uses coercion of strings to numbers in string.char and a replacement function as second argument to string.gsub).
This function can finally be used straightforwardly as unescape_string(f:read()).
I have inherited a cookbook that sets some attributes in the ./attributes/default.rb file as per normal.
However, we have a problem with one of the lines is, which is:
default["obscured"]["mysql"] = "#{node['jboss']['jboss_home']}/modules/com/mysql/jdbc/main"
When run, it write this into the node as:
{}/com/mysql/jdbc/main
I can confirm that the node['jboss']['jboss_home'] attribute exists and has correct values.
So, I cannot see any problem with the above, except that every other declaration of this type in our cookbooks has single quotes on the attribute to be set (i.e. left side), not double quotes. I haven't heard this of as being an issue before, but I am pretty new to chef.
Is there any rule that says they must be single quotes?
The answer is that there is no rule.
Using double-quotes in something like this is completely fine:
default["obscured"]["mysql"] = blah blah
The reason I know that is that I just found one being set, with double quotes, that actually works. :-)
What you have there is fine, how are you confirming the value of node['jboss']['jboss_home'] and how are you using it in the template?
In Ruby single and double quoted literals both become Strings but single quotes are relatively literal while double quotes allow backslash escapes and #{} interpolation.
You are most likely hitting the derived attributes problem:
https://coderanger.net/derived-attributes/
The attribute code in your cookbook is getting parsed before the jboss_home attribute is being set. One way or another the solution is to move the interpolation into recipe code.
You could just use a plain old ruby variable instead of the attribute you are trying to construct -- particularly if nothing else in your system ever sets that attribute.
You also should be able to delete the declaration from your attributes file and use this in recipe code as well:
node.default_unless["obscured"]["mysql"] =
"#{node['jboss']['jboss_home']}/modules/com/mysql/jdbc/main"
Although you need to place that statement early in your run_list, before you ever use node["obscured"]["mysql"] as an argument to any resource.
I am writing POST request for game I am trying to make scripts for. For this post, I am using the common req = urllib.request.Request(url=url, data=params, headers=headers) First though, I have a dictionary of the data needed for the request, and I must encode it with params = urllib.parse.urlencode(OrderedDict[])
However, this gives me a string, but not the proper one! It will give me:
&x=_1&y_=2&_z_=3
But, the way the game encodes things, it should be:
&x=%5F1&y%5F=2&%5Fz%5F=3
So mine doesn't encode the underscores to be "%5F". How do I fix this? If I can, I have the params that the game uses (in url, pre-encoded for), would I be able to use that in the data field of the request?
Underscores don't need to be encoded, because they are valid characters in URLs.
As per RFC 1738:
Unsafe:
Characters can be unsafe for a number of reasons. The space
character is unsafe because significant spaces may disappear and
insignificant spaces may be introduced when URLs are transcribed or
typeset or subjected to the treatment of word-processing programs.
The characters < and > are unsafe because they are used as the
delimiters around URLs in free text; the quote mark (") is used to
delimit URLs in some systems. The character # is unsafe and should
always be encoded because it is used in World Wide Web and in other
systems to delimit a URL from a fragment/anchor identifier that might
follow it. The character % is unsafe because it is used for
encodings of other characters. Other characters are unsafe because
gateways and other transport agents are known to sometimes modify
such characters. These characters are {, }, |, \, ^, ~,
[, ], and `.
All unsafe characters must always be encoded within a URL.
So the reason _ is not replaced by %5F is the same reason that a is not replaced by %61: it's just not necessary. Web servers don't (or shouldn't) care either way.
In case the web server you're trying to use does care (but please check first if that's the case), you'll have to do some manual work, as urllibs quoting does not support quoting _:
urllib.parse.quote(string, safe='/', encoding=None, errors=None)
Replace special characters in string using the %xx escape. Letters, digits, and the characters _.- are never quoted.
You can probably wrap quote() with your own function and pass that to urlencode(). Something like this (fully untested):
def extra_quote(*args, **kwargs):
quoted = urllib.pars.quote(*args, **kwargs)
return str.replace(quoted, '_', '%5F')
urllib.parse.urlencode(query, quote_via=extraquote)
I came across an interesting article. Which states unless until we are defining JSON we should use only single quote.
var foo = 'bar'; //Right way
var foo = "bar"; //Wrong way
Can anyone put light on this, why is it so?
Any help greatly appreciated.
The most likely reason is programmer preference / API consistency.
Strictly speaking, there is no difference in meaning; so the choice comes down to convenience.
Here are several factors that could influence your choise:
House style: Some groups of developers already use one convention or the other.
Client-side requirements: Will you be using quotes within the strings? (See Ady's answer).
Server-side language: VB.Net people might choose to use single quotes for java-script so that the scripts can be built server-side (VB.Net uses double-quotes for strings, so the java-script strings are easy to distinguished if they use single quotes).
Library code: If you're using a library that uses a particular style, you might consider using the same style yourself.
When using single quotes, any apostrophe needs escaping. ('Joe\'s got a cool bike.') When using double quotes, they don't. ("Joe's got a cool bike.") Apostrophes are much more common in English strings than double quotes.
Personal preference: You might thing one or other style looks better.
Please check following post that might be helpful for you When to Use Double or Single Quotes in JavaScript
First of all this is just a style guide.
You can define your ECMAScript strings the way you like them.
It is syntactically correct to use single quotes or double quotes for strings.
But according to JSON Specifications, a JSON value can be a string in double quotes, or a number, or true or false or null, or an object or an array.
I'm using a validation library that removes some common XSS attacks from the input to my web application. It works fine, and I'm also escaping everything I render to protect against XSS attacks.
The library contains this line in part of the XSS filtering process:
// Protect query string variables in URLs => 901119URL5918AMP18930PROTECT8198
str = str.replace(/\&([a-z\_0-9]+)\=([a-z\_0-9]+)/i, xss_hash() + '$1=$2');
xss_hash returns a string of random alpha-numeric characters. Basically it takes a URL with a query string, and mangles it a bit:
> xss('http://example.com?something=123&somethingElse=456&foo=bar')
'http://example.com?something=123eujdfnjsdhsomethingElse=456&foo=bar'
Besides having a bug (it only "protects" one parameter, not all of them), it seems to me the whole thing is itself a bug.
So my question is: what kind of attack vector is this kind of replacement protecting against?
If it's not really doing anything, I would like to submit a patch to the project removing it completely. And if it is legitimately protecting users of the library, I'd like to submit a patch to fix the existing bug.
xss_hash returns a string of random alpha-numeric characters.
Are they definitely random, or is it generated based on computable data?
It appears to be Security through obscurity: it's trying to replace all the &'s with xss_hash()'s so that the query is less readable. I'm guessing there is a part of the library which undoes this (i.e. treats all the xss_hash()'s in the string as &s for parsing purposes).
The code in question "protected query string variables" by replacing the & separating URL parameters with a random string, before doing some other processing that would remove or otherwise mangle ampersands. As Jay Shah pointed out, there was code just below that was meant to replace the query string ampersands, but another bug was preventing it from working as intended.