I am trying from last 5-8 hours not getting solution for xss prevent in magento,
I have already installed all latest patch in my magento.
I am using this script in catalog search input box
"><img src=x onerror=prompt(1);>
and i am getting this output :-
xss result
I have also tried with some validation like htmlEscape , strip_tags but none of working for me.
Can someone please help me ?
I Made many themes in magneto 1.9 , and tested many xss scripts but script is not triggered.
1. <script>alert('hello')</script> even
2. In url www.yourwebsite.com?query=<script>alert('hello')</script> or
3. <img src=x onerror="alert('Pop-up window XSS infected');" in search box but every string is by default escaped by Magneto itself.
This can be happen if you made your own custom search and didn't followed magento standard to pass the data to controllers and back to fronted.
You can use value="<?php echo $this->htmlEscape(input_values_here) ?>"
Example: credit
Magento Xss Prevention
<li class="wide">
<label for="street_1" class="required"><em>*</em><?php echo $this->__('Street Address') ?></label>
<div class="input-box">
<input type="text" name="street[]" value="<?php echo $this->htmlEscape($this->getAddress()->getStreet(1)) ?>" title="<?php echo $this->__('Street Address') ?>" id="street_1" class="input-text required-entry" />
</div>
</li>
JUst for knowledge :
You can learn more about xss from
XSS Tutorial
You can even check is there any message from Magento in your admin panel or any patches .
Perform these basic tests on your application:
Interact with your custom form/search box. Insert strings that contain HTML and JavaScript match characters into all application inputs, such as forms, URL parameters, hidden fields(!), or cookie values.
If your form doesn't correctly escape this string, you will see an alert and will know that something went wrong.
Wherever your custom form handles user-supplied URLs, enter javascript:alert(0) or data:text/html,alert(0).
Create a test user profile with data similar to the test strings above. Use that profile to interact with your application. This can help identify stored XSS bugs.
Related
I'm mainly a Wordpress guy and am trying to learn the ropes of Drupal 7. My question relates to templating best practices and security concerns. I am working with extremely complex designs (yeah designers right!?) so my markup needs to be clean and just right which I have found Drupal makes extremely difficult with the large hierarchy of template files and functions. Basically the workflow I have found that has been working for me is to override the output of specific content types that I need really specialized markup for at the node level.
So for instance : node--custom-content-type.tpl.php
Like I said I am a wordpress guy and am used to being able to run a database query, grab the exact field values that I want and use them however I want. I have been kpr or printing out the $variables array, studying what it contains, and grabbing values directly like so:
$link = $variables['field_link'][0]['url'];
$link_title = $variables['field_link'][0]['title'];
$target = $variables['field_link'][0]['attributes']['target'];
$text = $variables['field_main_text'][0]['safe_value'];
And then echo'ing out and using the variables in the markup exactly as I'd like:
<article class="getstarted-wrapper">
<a id="tocollege" target="<?php print_r($target); ?>" title="<?php print_r($link_title); ?>" href="<?php print_r($link); ?>"><img src="/sites/all/themes/amped/images/visiticon.png" /></a>
<a id="mapcollege" target="_blank" title="View Location In Google Maps" href="<?php echo $maplink; ?>"><img src="/sites/all/themes/amped/images/mapicon.png" /></a>
<div class="getstarted-top" style="background:<?php print_r($bg); ?>;">
<figure>
<img title="<?php print_r($auth_title); ?>" alt="<?php print_r($auth_alt); ?>" src="<?php print_r($auth_img); ?>" />
</figure>
</div><!--getstarted-top-->
<div class="getstarted-bottom">
<p><?php print_r($text); ?></p>
<a target="<?php print_r($target); ?>" title="<?php print_r($link_title); ?>" href="<?php print_r($link); ?>">Get Started</a>
<span>This will take you to <?php print_r($college_name); ?></span>
</div><!--getstarted-bottom-->
</article><!--getstarted-wrapper-->
I am wondering how this process matches up against best practices, what am I doing wrong, what am I doing right, and more importantly what are my security risks and how can I avoid them??
Every time you output a plain text string (ie anything that is not deliberately markup) into an HTML page, you need to escape it.
In plain PHP templates that is typically done with the htmlspecialchars() function. Drupal offers check_plain() as a short-cut, although not a very short one. You can define your own shorter cut to reduce the pain:
function h($s) {
echo htmlspecialchars($s, ENT_QUOTES, 'utf-8');
}
<a id="tocollege" target="<?php h($target); ?>" title="<?php h($link_title); ?>" href="<?php h($link); ?>">...
(I'm not sure what the use of print_r was for—this is traditionally used for producing readable structured-object output for debugging, but that format of output isn't generally what you want in a production web page, and in your example it was only being used for strings, where it makes no difference anyway.)
The correct approach with Drupal is to sanitize user input on output. Since Drupal has multiple modes of output (not just HTML) it's improper to sanitize on input, so when outputting HTML you can use Drupal's check_plain() function as bobince suggests. check_plain is one of several filter functions available for use, see https://drupal.org/node/28984 for more.
If you are overriding the output and accessing theme variables it is correct that the best practice to run check_plain (or other filter functions) yourself. If it's node properties then you can also use the 'safe' properties as described on the link above.
I'm building a site where staff will have their own section of the site: example.com/jones, example.com/smith, etc. jones and smith are template groups with the same templates inside (using Stash and Low Variables to keep it all DRY). Some users will have different needs for privacy. On one end their section will be public. On the other end some users will need to administer who can access their content (using Solspace friends).
However in the middle of that range are some who just want to protect against any random person seeing their content. I don't want to use members/member groups to manage this. I don't want visitors to need to register to see the content. A shared member account is an option, but we ruled that out because of other issues (what if the password is reset, comments being left under the same account, etc.
What we would like is to password protect the template group. The staff can let people know where to see their page, and let users know what the password is. This is all possible on a server level, but is is possible to allow the user to directly manage the password? Anything we can do to minimize how much we need to have hands on admin of this the better. A custom field and an add on that allows for this kind of security? I didn't see anything on Devot-ee and the methods on the forums don't do this. Bit of a longshot, but figured I'd ask.
Since you said you didn't want to be tied to actual member accounts and were OK with using a custom field to store an editable password...
I just recently did something similar that protected a group of entries using a custom field. It is similar to the approach outlined in this "Password Protected Content Made Simple" article. But instead of using PHP in the template I used Mo' Variables. And instead of using url_title I used a custom field (called client_password below).
In addition, I used the Session Variables plugin to check if the user was already "logged in" on subsequent page loads, preventing them having to enter the password again and again.
{!-- PASSWORD REQUIRED --}
{if client_password != ""}
{!-- if passed show content and set session --}
{if post:password == client_password}
{!-- protected content here --}
{!-- set session --}
{embed='embeds/_set_session' entry_id="{entry_id}"}
{!-- if session is valid show content --}
{if:elseif "{exp:session_variables:get name='logged_in'}" == "{entry_id}"}
{!-- protected content here --}
{!-- if failed show login --}
{if:elseif post:password != "" AND post:password != client_password}
<div id="protected">
<p>Incorrect password. Please try again.</p>
<br>
<form action="" method="post">
<strong>Password</strong><br />
<div>
<input name="password">
</div>
<input type="submit" class="submit" value="submit">
</form>
</div>
{!-- if first attempt show login and prompt --}
{if:else}
<div id="protected">
<p>This page is password protected. Please provide the password.</p>
<br>
<form action="" method="post">
<strong>Password</strong><br />
<div>
<input name="password">
</div>
<input type="submit" class="submit" value="submit">
</form>
</div>
{/if}
{!-- NO PASSWORD REQUIRED --}
{if:else}
{!-- protected content here --}
{/if}
I wanted to update this with the code I'm using to get htaccess and htpasswd working to protect by template group. It can be used in the same way as Alex's, but is an all or nothing approach. It has its own advantages, and disadvantages, but wanted to share it as an option.
First, I am using the native template behavior: example.com/group/template/url_title. I want to password protect some template groups, but outside of EE's members and member groups. ie a single user and password.
My htaccess file looks like this (from http://perishablepress.com/enable-file-or-directory-access-to-your-htaccess-password-protected-site/):
# We set some variables, matching URL's for which we do not wish to active
# the password protection
SetEnvIf Request_URI "^/privategroup.*$" private
# Setup the password protection
AuthName "Password Needed"
AuthGroupFile /dev/null
AuthType Basic
AuthUserFile /Users/user/Sites/example/.htpasswd
Require valid-user
# Add the exceptions for matched URL's
Order Deny,Allow
Deny from env=private
Satisfy any
The htpasswd file should be above webroot, but for testing I left it in webroot. The AuthUserFile line tells Apache where to find the file with the usernames and passwords. This must...MUST be an absolute path. I was using relative and got 500 errors. You need to use terminal or some other tool to make this file. http://developer.apple.com/library/Mac/#documentation/Darwin/Reference/ManPages/man1/htpasswd.1.html
The result is that directory requires a username and password. Right now it will accept any valid user in my htpasswd file. However I can change that by specifying a specific user (require user john tim lisa) or groups.
There you have it. Keep people out of specific template groups without using any native EE functionality.
I will be honest, I'm not sure if this fits your needs or not. It's not clicking that it will though, I've never tried it before and would need to actually give it a go to know for sure that it does or does not fit.
I will post it just the same as it may help you or someone else down the road:
http://koivi.com/ee-entry-auth-dir/
Have you looked at using the HTTP Authentication option under Template Access Restrictions? It uses a member password for authentication, but doesn't require the member to actually be logged-in.
You say you "don't want to use members/member groups to manage this", but then that you want to "allow the user to directly manage the password" ... surely using the built-in member system is the easiest way?
Using the POST HTTP method, Site Scanner found that :
The following resources may be vulnerable to cross-site scripting (extended patterns) :
The 'email' parameter of the /customer/account/forgotpasswordpost/ CGI :
/customer/account/forgotpasswordpost/ [email=508 src=http://www.example.
com/exploit508.js]
As far I see code, Magento senitize the _GET/_POST. How can I get fixed this?
I guess this will depend on what version of Magento you are running. The default location for the template in question can be found at app/design/frontend/base/default/template/customer/form/forgotpassword.phtml. The only value that is user editable that is echo'd out to the screen is the e-mail address, certainly in Magento 1.6 this is being passed through the template blocks htmlEscape method, but it's worth checking that it is in your version of Magento.
<input type="text" name="email" alt="email" id="email_address" class="input-text required-entry validate-email" value="<?php echo $this->htmlEscape($this->getEmailValue()) ?>" />
If you find that it already is then it would be worth checking that this template isn't being overloaded in your current theme.
I've read a couple of related questions on this, but they don't answer my question directly. Developer tools like Firebug allow anyone to see and manipulate form data before a form is sent. A good example of this is adjusting the value of a hidden "member ID" field so that the form submission is credited to another user.
What are the best ways to prevent this type of tampering? My research suggests moving sensitive form inputs to a server-side script, but are there any other options or considerations?
I'm familiar with PHP and jQuery, so my ideal solution would use one or both of those languages.
You can't use jQuery for security since it's all handled on the client side.
In your example just use a PHP session in staed of a hidden input field, because as you rightfully noted this can be manipulated.
Using sessions would look something like the following:
login page
<form action="login.php" method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" name="submit" value="submit">
</form>
login.php
// you have to include this on every page to be able to user sessions.
// also make sure that you include it before any output
session_start();
//Always sanitize the user input before doing any db actions.
//For example by using: `mysql_real_escape_string()` ( http://php.net/manual/en/function.mysql-real-escape-string.php ).
// check user credentials against db
$_SESSION['user'] = $dbresult['username'];
page-where-userid-is-required.php
session_start();
if (!isset($_SESSION['user'])) {
// user is not logged in!
} else {
// use user info to place order for example
}
The session will be active until the user closes his browser / until the session expires (which is a PHP setting)
The above is just some sample code to give you an idea.
It works smaller projects, however as projects get more complex I would suggest going for the MVC (Model, View, Controller) way. ( http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller )
But that's just a whole other story :)
Here are a few basic suggestions:
You need to validate form inputs using a server-side (PHP) script.
Instead of relying on sensitive pieces of information, such as member ID, from the form you could instead cache such data in your server session. That way there is no way for a malicious user to change the data on the fly.
You can still use jQuery validation as a convenience to catch basic input problems, but you can only trust data that is validated using server-side code.
Examine this example. It is in PHP, but you should be able to pick up what is happening if you don't know PHP.
echo 'You searched for "' . $_GET['q'] . '"';
Now, obviously, this is a bad idea, if I request...
http://www.example.com/?q=<script type="text/javascript">alert('xss');</script>
OK, now I change that GET to a POST...
echo 'You searched for "' . $_POST['q'] . '"';
Now the query string in the URL won't work.
I know I can't use AJAX to post there, because of same domain policy. If I can run JavaScript on the domain, then it already has security problems.
One thing I thought of is coming across a site that is vulnerable to XSS, and adding a form which posts to the target site that submits on load (or, of course, redirecting people to your website which does this). This seems to get into CSRF territory.
So, what are the ways of exploiting the second example (using POST)?
Thanks
Here is an xss exploit for your vulnerable code. As you have aluded to, this is an identical attack pattern to POST based CSRF. In this case i am building the POST request as a form, and then I call .submit() on the form at the very bottom. In order to call submit, there must be a submit type in the form. The post request will immediately execute and the page will redirect, it is best to run post based csrf of exploits in an invisible iframe.
<html>
<form id=1 method="post" action="http://victim/vuln.php">
<input type=hidden name="q" value="<script>alert(/xss/)</script>">
<input type="submit">
</form>
</html>
<script>
document.getElementById(1).submit();//remote root command execution!
</script>
I also recommended reading about the sammy worm and feel free to ask any questions about other exploits I have written.
All I would need to do to exploit this is to get a user to click a form that sends a tainted "q" post variable. If I were being all nasty-like, I wouldcraft a form button that looks like a link (or even a link that gets written into a form POST with Javascript, sort of like how Rails does its link_to_remote stuff pre-3.0).
Imagine something like this:
<form id="nastyform" method="post" action="http://yoururl.com/search.php">
<input type="submit" value="Click here for free kittens!">
<input type="hidden" name="q" value="<script>alert('My nasty cookie-stealing Javascript')</script>" />
</form>
<style>
#nastyform input {
border: 0;
background: #fff;
color: #00f;
padding: 0;
margin: 0;
cursor: pointer;
text-decoration: underline;
}
</style>
If I can get a user to click that (thinking that he's clicking some innocent link), then I can post arbitrary data to the search that then gets echoed into his page, and I can hijack his session or do whatever other nasty things I want.
Post data isn't inherently more secure than get data; it's still user input and absolutely cannot be trusted.
CSRF attacks are a different class of attack, where some legitimate action is initiated without the permission of the user; this has the same sort of entry vector, but it's a classic XSS attack, designed to result in the injection of malicious Javascript into the page for the purpose of gaining session access or something similarly damaging.