Say i have a form with which user inputs some information and is submited to server using php and in PHP code i have say
$data = $_POST['data'];
// or
$data = strip_tags(#$_POST['data']);
I want to know of the strip_tags() is enough to stop javascript injection through html forms. If not how else can this be prevented. I have read here.
And also say i input javascript:void(document.bgColor="blue") in the browser address bar, this changes the whole site background color to blue. How can javascript injection through the address bar be prevented.
Thanks.
i suggest to use htmlspecialchars when ever you want to output something to browser
echo htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
checkout this
For question 2, I'm not sure if that's even possible to prevent. It's not something I've ever considered before. It sounds like you're trying to prevent executing any javascript that wasn't included by you on the page, which would also mean blocking the devtools in the browser from executing anything in the console. This could potentially be hostile to your users, e.g. if they wanted to use a bookmarklet from Instapaper.
For 1, ultimately your goal is to avoid including this injected javascript from the form when you generate a new page. When you output the data from the form, you can wrap it in htmlspecialchars.
It's depend which output you are trying to get.
In some cases , you'll want to leave the HTML tags including script tags ,but you want that those elements will not run when you output them, in that case you should use htmlspecialchars($_POST['data']), (It's suggested to define also utf8 as the third parameter).
But if you want to remove entierly the tags than strip_tags will prevent XSS
One function cannot fully protect you from script injection. Consider the following program:
<?php
if(isset($_POST['height']))
$height=htmlspecialchars($_POST['height'], ENT_QUOTES, 'UTF-8');
else $height=200;
if(isset($_POST['width']))
$height=htmlspecialchars($_POST['width'], ENT_QUOTES, 'UTF-8');
else $width=300;
echo("
<!DOCTYPE html>
<html>
<body>
<iframe src='whatever' height=$height width=$width>
</iframe>
</body>
</html>
");
The input is sanitized, but javascript will still be executed through a simple injection vector like:
300 onload=alert(String.fromCharCode(88)+String.fromCharCode(83)+String.fromCharCode(83))
You still need to quote your attributes or you are vulnerable like this example.
Another semi-common injection vector exists when user input is echoed into javascript comments, and you can inject new lines or close the comment. I blame it on the 'this shit doesn't work as it should, but let's keep it around in a comment'-style of development.
Note: The XSS protection of many browsers will not run my simple example. If you want to try it use one without protection, or find a vector that defeats it (not sure if there is one for e.g. Chrome).
Related
Consistently on Stack Overflow, the question of how to redirect a user upon input or after values have been altered is raised, and in PHP, the standard answer is to modify the headers to achieve this.
However, in PHP, headers must be altered at the beginning before any html or text is posted.
So regularly I post my own personal solution, which is as follows:
"End the PHP tag when you would like to perform the redirect and write the following:
<script>
location.replace("Whatever.php");
</script>
And then finally pick up your PHP tag once more to complete your code."
Everytime I have posted that, the answer has been downvoted to oblivion almost immediately. However, to my knowledge, it works, in it's entirety.
So my question is, why is this downvoted so heavily? What is it about using this solution that is so frowned upon?
Example of Full Usage (excluding escape functions):
if(isset($_GET['role'])){ //If value set in GET
$role = $_GET['role']
if($role == "Admin"){ ?> // Drop PHP tag
<script>location.replace("AdminPage.php");</script> //Solution
<?php else{ ?>
<script>location.replace("StandardPage.php");</script> //Solution
<?php } } ?> //Pick up Tag final time and Close isset.
Just because it does work doesn't mean you shouldn't prefer the more fitting way to do it. So why is a header re-direct preferable, you might ask?
JavaScript can be disabled, and if you redirect because of needed authorization (it looks like you're redirecting based on that in your example), someone could just disable JavaScript and see the "secret stuff" on that page, maybe even trigger an action via a link (deletion of data), if the backend is missing the authorization-check.
If using a header redirect, that will happen as soon as the client has fetched the headers. No content will have to be transfered (it still might in some cases, but using exit; right after the Location header will prevent that). That means less overhead and faster reaction times for the end user.
Firstly, a client can just turnoff the Javascript. So then and there your code is broken immediately.
Don't give client to any chance to alter or break your work flow.
Secondly bad practice because unmanageable. Keep it separate style, scripts and php codes.
Let's say that a simple web application, like below, runs, utilizing Simple HTML Dom Parser.
<?php
include('simple_html_dom.php');
$html = file_get_html('http://someurl.com');
echo $html;
?>
As expected, everything comes up EXCEPT for one element, a div of class .addedDiv, which appears to be injected by JS. In the simplest and most inclusive way, can you please demonstrate how that one element can be retrieved with the minimal amount of code, hopefully with an example,
(update ) preferably inline and easy to implement for most people, be it with PHP, AJAX, or, I don't know, iFrame hack? Thanks in advance for any and all help.
UPDATE:
Also, if it helps, I don't actually need (or want) it outputted along with everything else. I just need an attribute from it to simulate some additional functionality. Therefore, if it is of any difference, I do not need to have to have a '$html' that outputs everything of a website to the screen (if I did, I'd just use an iframe).
I think you can use phantomjs module. you need to require install it.
phantomjs is command line utility, so in php you can execute it by exec() command and get expected foutput.
For more you need to learn how to get content of HTML after modified by JS from here http://phantomjs.org/api/webpage/property/content.html
Maybe a stupid question but it is possible to write a form sort of thing that you can fill in which either writes or replaces the code in the file?
For example I have a result table with possible results. Instead of using either a database or replace the code in my file manually I'd like to write a form which changes the code for me when I fill it in. Sort of like a database but then just in the file itself.
Is this possible?
Wit kind regards
Simple answer: Yes, it is possible, but not recommended.
Elaborating the answer: The reason it is not recommended is because you are opening your doors to hackers that could use XSS (Cross Site Scripting) attacks, unmasking your site, or many other possibilities.
If however you are just curious on how you would modify the code from a form, you can do it as follows.
$new_code = $_POST['newcode'];
$myFile = fopen('table.html', 'w');
fwrite($myFile, $new_code);
fclose($myFile);
A file called table.html would then be created in the same location as the page that is running the previous code. If you want to place the file in another page, you could just add a relative or absolute path to the name, for instance:
$myFile = fopen('../folderA/table.html', 'w');
$_POST is a php superglobal. It is very often used in forms, and if you aren't sure how to use it, there are many great tutorials online.
If you wanted a php file, the code would be the same, except you would change the name of the file from table.html to table.php.
Let me know if that helped!
Considering issues like CSRF, XSS, SQL Injection...
Site: ASP.net, SQL Server 2012
I'm reading a somewhat old page from MS: https://msdn.microsoft.com/en-us/library/ff649310.aspx#paght000004_step4
If I have a parametrized query, and one of my fields is for holding HTML, would a simple replace on certain tags do the trick?
For example, a user can type into a WYSIWYG textarea, make certain things bold, or create bullets, etc.
I want to be able to display the results from a SELECT query, so even if I HTMLEncoded it, it'll have to be HTMLDecoded.
What about a UDF that cycles through a list of scenarios? I'm curious as to the best way to deal with the seemingly sneaky ones mentioned on that page:
Quote:
An attacker can use HTML attributes such as src, lowsrc, style, and href in conjunction with the preceding tags to inject cross-site scripting. For example, the src attribute of the tag can be a source of injection, as shown in the following examples.
<img src="javascript:alert('hello');">
<img src="java
script:alert('hello');">
<img src="java
script:alert('hello');">
An attacker can also use the <style> tag to inject a script by changing the MIME type as shown in the following.
<style TYPE="text/javascript">
alert('hello');
</style>
So ultimately two questions:
Best way to deal with this from within the INSERT statement itself.
Best way to deal with this from code-behind.
Best way to deal with this from within the INSERT statement itself.
None. That's not where you should do it.
Best way to deal with this from code-behind.
Use a white-list, not a black-list. HTML encode everything, then decode specific tags that are allowed.
It's reasonable to be able to specify some tags that can be used safely, but it's not reasonable to be able to catch every possible exploit.
What HTML tags would be considered dangerous if stored in SQL Server?
None. SQL Server does not understand, nor try to interpret HTML tags. A HTML tag is just text.
However, HTML tags can be dangerous if output to a HTML page, because they can contain script.
If you want a user to be able to enter rich text, the following approaches should be considered:
Allow users (or the editor they are using) to generate BBCode, not HTML directly. When you output their BBCode markup, you convert any recognised tags to HTML without attributes that contain script, and any HTML to entities (& to &, etc).
Use a tried and tested HTML sanitizer to remove "unsafe" markup from your stored input in combination with a Content Security Policy. You must do both otherwise any gaps (and there will be gaps) in the sanitizer could allow an attack, and not all browsers full support CSP yet (IE).
Note that these should be both be done on point of output. Store the text "as is" in your database, simply encode and process for the correct format when output to the page.
Sanitize html both on the client and on the server before you stuff any strings into SQL.
Client side:
TinyMCE - does this automatically
CKEditor - does this automatically
Server side:
Pretty easy to do this with Node, or the language/platform of your choice.
https://www.realwebsite.com
the link above shows www.realwebsite.com while it actually takes you to www.dangerouswebsite.com...
<a '
href="https://www.dangerouswebsite.com">
https://www.realwebsite.com
<'/a>
do not include the random ' in the code I put it there to bypass activating the code so you can see the code instead of just the link. (btw most websites block this or anything if you add stuff like onload="alert('TEXT')" but it can still be used to trick people into going to dangerous websites... (although its real website pops up on the bottom of your browser, some people don't check it or don't understand what it means.))
I'm creating an app that retrieves the text within a tweet, store it in the database and then display it on the browser.
The problem is that I'm thinking if the text has PHP tags or HTML tags it might be a security breach there.
I looked into strip_tags() but saw some bad reviews. I also saw suggestions to HTML Purifier but it was last updated years ago.
So my question is how can I be 100% secure that if the tweet text is "<script> something_bad() </script>" it won't matter?
To state the obvious the tweets are sent to the database from users so I don't want to check all individually before displaying them.
You are NEVER 100% secure, however you should take a look at this. If you use ENT_QUOTES parameter too, currently there are no ways to inject ANY XSS on your website if you're using valid charset (and your users don't use outdated browsers). However, if you want to allow people to only post SOME html tags into their "Tweet" (for example <b> for bold text), you will need to take a deep look at EACH whitelisted tag.
You've passed the first stage which is to recognise that there is a potential issue and skipped straight to trying to find a solution, without stopping to think about how you want to deal the scenario of the content. This is a critical pre-cusrsor to solving the problem.
The general rule is that you validate input and escape output
validate input
- decide whether to accept or reject it it in its entirety)
if (htmlentities($input) != $input) {
die "yuck! that tastes bad";
}
escape output
- transform the data appropriately according to where its going.
If you simply....
print "<script> something_bad() </script>";
That would be bad, but....
print JSONencode(htmlentities("<script> something_bad() </script>"));
...then you'd would have done something very strange at the front end to make the client susceptivble to a stored XSS attack.
If you're outputting to HTML (and I recommend you always do), simply HTML encode on output to the page.
As client script code is only dangerous when interpreted by the browser, it only needs to be encoded on output. After all, to the database <script> is just text. To the browser <script> tells the browser to interpret the following text as executable code, which is why you should encode it to <script>.
The OWASP XSS Prevention Cheat Sheet shows how you should do this properly depending on output context. Things get complicated when outputting to JavaScript (you may need to hex encode and HTML encode in the right order), so it is often much easier to always output to a HTML tag and then read that tag using JavaScript in the DOM rather than inserting dynamic data in scripts directly.
At the very minimum you should be encoding the < & characters and specifying the charset in metatag/HTTP header to avoid UTF7 XSS.
You need to convert the HTML characters <, > (mainly) into their HTML equivalents <, >.
This will make a < and > be displayed in the browser, but not executed - ie: if you look at the source an example may be <script>alert('xss')</script>.
Before you input your data into your database - or on output - use htmlentities().
Further reading: https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet