I have a url like this
http://www.example.com/?input=userinput
although i did xss injection filters
strip_tags ();
but look at this , i take this input and put it in a url like this
imagine user could write this code at his user input section
onMouseOver%3dalert%2839793%29%2f%2f
This will add onMouseOver event to my url !!!
Please take a look at the OWASP XSS Prevention Cheat Sheet. It will explain all of this in detail:
https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
To answer the specific topic mentioned here, you need to url encode the input before printing it in the page as a part of the url. For other data inside HTML attributes you need to apply HTML attribute encoding and possibly javascriot encoding if it's in a event handler like onclick.
Related
I'm working on a website where there is going to be a lot of user generated content. As an WYSIWYG editor I'm using tinyMCE. As a template engine, I'm using ejs.
In order to prevent XSS I decided to use xss npm package.
I'm using these custom rulles:
const strict = {
whiteList: {},
}
const withTags = {
whiteList: {
div: [],
strong: [],
em: [],
br: [],
ul: [],
li: [],
ol: [],
blockquote: [],
},
}
Let's say a user uses text area and submits this code:
<script>alert("hi")</script>
In my DB it's saved this way:
<script>alert("hi")</script>
Now, when the content is rendered by ejs some content is rendered with escaped output (<%= %>). Rendered escaped output (html page) looks like this:
<script>console.log("test")</script>
However, some content is rendered with ejs unescaped raw output (<%- %>). Html will look this way:
<script>console.log("test")</script>
I have 2 questions:
Because < and > are escaped as < and > is it safe to render ejs unescaped output?
Is what I'm doing generally enough for XSS protection?
Thank you very much!
First of all your data probably isn't saved in database the way you presented. In all likelihood it's stored there without any encoding (as it should be).
EJS in itself, when used correctly, takes care of encoding output for you so that you can safely construct parameterized HTML. But in your case you want to disable this protection to render raw HTML, so yes, you must be careful. There are a couple of security controls at your disposal.
1. DOMPurify
I haven't used the xss library personally, it seems to have a lot of downloads and probably it's not a bad option. But DOMPurify is probably better. It also doesn't require configuration and has built-in support for trusted-types (I'll get to that in a minute).
You would use it twice. First on server-side when the HTML is submitted by the user, and second on client-side when the HTML is rendered by EJS.
If you are serious about security then you will connect anomaly alerts from the server-side purification to your SIEM/SOC etc. Then you will know when someone has attempted an XSS attack on your website.
2. Sandboxed Iframes
Another client-side control that you can implement is sandboxed iframes. Instead of just rendering the HTML on the page, you create an IFRAME, give it a properly configured sandbox attribute, and then set the purified HTML as the content. Now even if something goes wrong with the purification, the malicious HTML would be isolated in its own world.
3. Content Security Policy
The coolest and (when used properly) most effective defence against XSS is CSP. How it works is that you give your website restrictions such as "do not execute scripts", "do not load images", etc. And then you allow the scripts that you do want to execute, and nothing else. Now if an attacker manages to inject a script, link, form, etc. on the page, it will not work because it hasn't been specifically allowed.
I've written about CSP at length here, you will even find specific examples for your case (NodeJS and EJS) with CodeSandbox examples on that article. And in general about XSS protection you can read more here.
Hope this helps!
I'm trying to find something that will return an exception upon finding anything that even remotely looks like HTML or Javascript. I've figured out how to do it for individual views, but it's not a scalable solution, and ultimately I need to prevent code from being saved to the database no matter what view gets targeted by the injection attack.
Here is the functionality I'm looking for.
ILLEGAL_CHARS = '<>[]{}():;,'.split()
# bunch of code in between
for value in [company_name, url, status, information, lt_type, company_source]:
if any(char in value for char in ILLEGAL_CHARS):
raise Exception(f"You passed one of several illegal characters: {ILLEGAL_CHARS}")
I'm using django rest framework so I have to handle it on the backend. Thanks.
actually you don't nead to sanitize any user input because when you show them int the template the jinja {{object}} will make sure that no html or java script will be executed until you mark them as safe {{object|safe}} but if you want want not to save them in database that might help Sanitizing HTML in submitted form data
I use Postman for REST API testing and parametrize tests with global variables.
I should put a phone number into GET request: /path/get?phone={{phone}} but leading + sign in the phone number is interpreted as a space.
What is the syntax to URL encode global variables in Postman? Is it possible to run JS encodeURIComponent() on variable in URL?
I am late but still worth it:
Just highlight and right click the part of url you want to encode. Select encodeURIComponent
That's it.
Use the Pre-request scripts (it's next to body) for this:
var encoded = encodeURIComponent({{phone number}});
or
var encoded = encodeURIComponent(pm.environment.get("phone number"));
and to proceed, use:
pm.environment.set("encoded phone number", encoded);
And set your URL to /path/get?phone={{encoded phone number}}
Just a shortcut to Mohhamad Hasham' answer.
You can encode and decode direct in the Params Value field:
The trick is to get your environment variable in the pre-request script and then set it after encoding it
var encoded = encodeURIComponent(pm.environment.get("phone"));
pm.environment.set("encoded phone number", encoded);
This will work as well:
var encoded = encodeURIComponent(pm.request.url.query.get("phone"));
pm.request.url.query.remove("phone");
pm.request.url.query.insert("phone", encoded);
I came across this question looking for an answer to a similar question. For me, the variable was a JSON object. The endpoint I needed to hit was expecting an object list as a query parameter and I have no way to change that to be the request body.
As much as some of the answers helped, I ended up coming up with a combined solution. Also, some of the code given in other answers is outdated as Postman has updated their API over the years, so this uses methods that work on 7.22.1.
pm.environment.set("basicJSON", '[{"key1":"value1","key2":"value2"},{"key1":"value1","key2":"value2"}]')
var encoded = encodedURIComponent(pm.environment.get("basicJSON"))
pm.environment.set("encodedJSON", encoded)
This solution requires that both basicJSON and encodedJSON exist as environment variables. But what was important for me was the ease of editing the object. I didn't want to have to decode/encode constantly to change values, and I didn't want to have to open the environment variables dialogue. Also, it's important to note the single-quotes around the object. Excluding them or using double-quotes would cause Postman to send something like "[object Object]" which is useless to an endpoint expecting actual JSON.
I had similar problem with braces { and } in query parameter.
By turning off the following setting it started working for me.
For the postman version 9.28.4 ==>
You can use 2 methods:
By selecting the part of the url in url bar -> right click -> EncodeURLComponent. (screenshot attached)
You can also use "pre-request script" tab of postman and write the script for the variable manually. (screenshot attached)
The problem with right-click => Encode URI Component is that it destroys the raw value of that parameter. You can use the following pre-request script to overcome this (which also works for cases where you have disabled that param):
// queryParam is of type https://www.postmanlabs.com/postman-collection/QueryParam.html
if ((queryParam = pm.request.url.query.one("name_of_your_query_param")) !== undefined
&& queryParam.disabled !== true) {
queryParam.value = encodeURIComponent(queryParam.value);
}
Click the Params button to open the data editor for URL parameters. When you add key-value pairs, Postman combines everything in the query string above. If your URL already has parameters - for example, if you are pasting a URL from some other source. Postman splits the URL into pairs automatically.
https://www.getpostman.com/docs/v6/postman/sending_api_requests/requests
POSTMAN's documentation on building requests in the section "sending parameters" is helpful here. You can encode path data by simply encoding the URL with a colon, listing the key name of the encoded element, and then a new section will appear below the query parameters allowing you to customize values and add a description, just as we do with query params. Here's an example of encoding the URL for a GET request:
https://somesite-api-endpoint/:record/get
And here's what the display looks like after you add path data. Any value you add in the path variables section will automagically update the URL with your data.
I want to insert a URL filter and I would like the URL to be hard to dechiffre.
For example .*porn\.* in a way maybe that it uses the ASCII code for the letters in hex form .
Of course, the example is obvious and I definately will leave that one as it is ;)
But for the others I would like them to be hard to read!
Thx!
You can use the $_GET function in PHP to pull an ID out of the URL and display it that way, similar to Youtube with their "watch?v=". I recently did one using "?id=49" (I only have a few pages ATM, I will have about 70 soon). What I did is use a database with a song_id to index the information. I use the same basic layout, but you can use the ID to access information wrapped in PHP so that it doesnt get sent to the browser but will still display the page you want.
Or if you really want it to look crazy, you could use a database using the SHA() or MD5() function to encrypt it.
and your display will look like /page.php?id=21a57f2fe765e1ae4a8bf15d73fc1bf2a533f547f2343d12a499d9c0592044d4.
I was about ready to start giving a jqgrid in a django app greater functionality (pagination, searching, etc). In order to do this it looks as though jqgrid sends its parameters in the GET to the server. I plan to write an urlpattern to pull out the necessary stuff (page number, records per page, search term, etc) so I can pass it along to my view to return the correct rows to the grid. Has anyone out there already created this urlpattern I am in search of?
Thanks much.
The answer to this was simpler than I realized. As stated in Chapter 7 of the djangobook in the section titled "Query string parameters" one can simply do something as follows, where "someParam" is the parameter in the query string you want to retrieve. However, Django is designed to be clean in that address bar at the top of the page so you should only use this option if you must.
The query string might look something like this.
http://somedomainname.com/?someString=1
The view might look like this.
def someView(request):
if 'someParam' in request.GET and request.GET['someParam']:
someParam = request.GET['someParam']
Hopefully this is of some help to someone else down the road.