Someone had try to steal my css file to use at his site. Can i somehow block CSS file from external access, but not damage my site? Somehow through htaccess or something. Thanks for your advice, any help appreciated.
Generate your css with PHP like style.css.php and in the code accept a token which refreshes every second. Your main page will include it using the current token src="style.css.php?token=abc123". If the token is valid, it serves it up. If the token is expired, it doesn't.
Dumbest solution ever. Endless workarounds, but might help against that guy who wants to steal your CSS. Worth a try and a good laugh.
Step 1: Create a table css_security_force in your database with one column token
Step 2: Create a cron that runs every second to update the token (now THAT's secure):
UPDATE css_security_force SET token = md5( NOW() );
Step 3: In your PHP head grab the token from the css_security_force table and set it as a variable $token then reference that token in the CSS link:
<link rel="stylesheet" href="style.css.php?token=<?=$token?>" />
Step 4: In your style.css.php file, grab the token from the database and check it against the query param.
if ($_GET['token'] == $token) {
echo <<<CSS
body {
background-color : yellow;
color : pink;
}
CSS;
} else {
echo 'Stop stealing my CSS!!!!!!';
}
Sit back and watch your foe's plans crumble before him.
EDIT
I got curious and made a working demo (Took it down after a couple days of 1 second db updates for sanity purposes, but you can easily recreate with the source posted below).
Here is the source on Github
No. This makes no sense. Your CSS file must be available to anyone who can view your site if you want your pages styled.
Who cares if someone uses your style?
Simply put you cannot block it because the browsers have to have access to them. It is just one of those things you should not worry about. If it were possible, many sites like Facebook and Twitter would be blocking it.
Related
I have existing URLs that used the URL hash to provide extra data to javascript after page load, e.g.
http://www.example.com/my/directory/#/foo/bar/
I'm implementing jquery.history for something else, but also need to make those old URLs continue to work (e.g. if someone might have bookmarked it with the /#... part).
However on page load the plugin is stripping out everything between the domain and the /#, e.g. the URL ends up becoming:
http://www.example.com/foo/bar/
This isn't happening in IE 9, but is happening in Firefox and Chrome.
Any ideas? I don't consider this a bug in the plugin, but I'm happy to amend the unminified source files for my own usage, if someone suggests a fix that won't break the rest of its functionality.
One possible idea - I no longer care about what that extra data in the URL after the # is, so could perhaps remove that part from the URL before the history plugin does anything to it. I'm not entirely sure yet at what point that could be, or more specifically when the plugin is amending the URL on page load.
In the end I did what I mentioned at the end of my question. Added this bit of inline JS prior to the call to the history plugin js file:
(function(){
if (document.location.hash.length !== 0) {
document.location.hash = '';
}
})();
At worst we end up with the URL still having a trailing # at the end, but as it doesn't have #/ then the history plugin doesn't then mess it up.
I recently asked a question about LAMP stack not allowing posting of <script> tag via textarea, the request is killed by the apache i guess as the $_POST, $_GET and $_REQUEST fields are all empty.
I was just wondering how does wordpress allow users to add widgets, updated template files and create pages using a textarea control that allows <script> tag.
UPDATE
I've created a pastebin entry for the form here: http://pastebin.com/1Jaz9rRz
Basically it is an auto generated form, I've copy pasted from the source code.
UPDATE
I've moved the code for testing to the server here: http://www.007softwares.com/testing.php
The form is being posted to itself, i've echoed the $_REQUEST array to see what was posted. You can see when you just submit the form, fields are visible and when you type script tag the error page appears. Hope this helps.
This is quite certainly some misguided security mechanism either in your browser, or (more likely) on the server.
As said, check Suhosin out using phpinfo():
<?php phpinfo(); ?>
You should see some mention of the word "Suhosin" or "Hardened PHP" in the resulting output.
Also I wouldn't rule out mod_security - the errors you say you got when adding the lines disabling it in .htaccess might have some other reason. It could for example be configured that it's impossible to turn off through .htaccess.
Ask your web host whether they have anything enabled security-wise that might be causing this.
The LAMP stack doesn't care what text is submitted via a TEXTAREA. The script/app that receives the form input may have some logic in it which kills the process if it sees a SCRIPT tag but in general you can submit whatever text you want.
Your phpinfo() says that string.strip_tags is registered as a stream filter. This might be causing your issue.
Also, your filter extension may be configured to strip although that isn't as likely.
When the user submits a < p > tag it works as expected. When the user submits a < script > tag a 404 is returned. This leads me to believe apache is using mod_security with a configuration similar to:
SecFilterDefaultAction "deny,log,status:404"
SecFilter "<script"
What is the best way to handle style that that is user-customized? Just as an example of the result I'm looking for, this would suffice:
body {
color: {{ user.profile.text_color }};
}
However, serving CSS as a view seems like it would cause a significant amount of overhead in a file that is constantly requested, so this is probably not a good solution.
The user does not have access to the CSS files and we must assume that they have no web development knowledge.
However, serving CSS as a view seems like it would cause a significant amount of overhead in a file that is constantly requested, so this is probably not a good solution.
And what if you would generate that CSS once?
Default CSS is: /common/css.css
Member customize CSS, now <link /> elements points to /user-specific/123.css?ts=123123123. 123 is of course an identifier of the member, and ts parameter contains a timestamp - a date of last CSS modification
Make sure that your CSS generator sets proper HTTP headers responsible for client-side caching
User browser request a CSS file - server replies with simple 304 Not Modified header - there is no need for any script execution or contents download
When member modifies his CSS then you just update ts - once again just a single request is needed
Do the CSS dynamically via a view as normal, but use aggressive caching so that it loads quickly.
You can try django mediagenerato, actually I read this Q and I was searching for solution like you, then I found that Django-mediagenerator
I didn't tried it yet but it seams to be a solution.
I'm using a very simple Stylesheet Switch by php. It was fine all along but days ago I turn on Caching mode and now it only work for login user. If turn off Caching mode, it will work again for both user.
Basically the code looks like this
In the page.php header
<?php
if(isset($_COOKIE['style'])){
$style=$_COOKIE['style'];
} else {
$style='green';
}
?>
<link type="text/css" rel="stylesheet" href="/css/<?php echo $style ?>.css">
It switch by
Blue
In the switch.php
<?php setcookie('style', $_GET['style'], time()+31536000);
header('Location:'.$HTTP_SERVER_VARS['HTTP_REFERER']);
?>
I did many research but couldn't find the right way. Please help if you can. Thank you
Hmm, I don't see why you can't just use a client-side style switcher, as in http://www.alistapart.com/articles/alternate/. There are other methods of doing it purely client-side, but it seems a bit overkill to request an entire new page to switch styles.
Also, caching creates a static page to serve up in lieu of dynamically creating a new page for every hit, so the cached page is probably getting served up to whoever isn't getting the style switching.
From my understanding/experience standard drupal caching is only for non-logged in users. There is at least one module that allows for authenticated user caching, but it's not in Core, authcache:
http://drupal.org/project/authcache
An old article that explains druapl caching techniques. Still has some good information in there: http://n0tablog.wordpress.com/2007/11/19/drupal-caching/
I'm trying to execute an HTTP GET from my website to another website that is brought in via iframe.
On Firefox, you can see in the source that the correct url is in the iframe src along with it's correct parameters-- and it works.
On IE, you can see in the source that the correct url is in the iframe src along with it's correct parameters-- and it doesn't work...
Is there something about IE that doesn't let you pass parameters through an iframe in the querystring?
I've tried refreshing the iframe in IE, I've tried refreshing my page & the iframe in IE, and I've tried copying the url and re-pasting it into the iframe src (forcing it to refresh as if I just entered it into the address bar for that iframe window). Still no luck!
Anyone know why this is happening, or have any suggestions to try to get around this?
Edit: I cannot give a link to this because the site requires a password and login credentials to both our site and our vendor's site. Even though I could make a test account on our site, it would not do any good for the testing process because I cannot do the same for the vendor site. As for the code, all it's doing is creating the src from the backend code on page load and setting the src attribute from the back end...
//Backend code to set src
mainIframe.Attributes["src"] = srcWeJustCreated;
//Front end iframe code
<iframe id="mainIframe" runat="server" />
Edit: Problem was never solved. Answer auto accepted because the bounty expired. I will re-ask this question with more info and a link to the page when our site is closer to going live.
Thanks,
Matt
By the default security settings in IE query parameters are blocked in Iframes. On the security tab under internet options set your security level to low. If this fixes your problem then you know that is your issue. If the site is for external customers then expecting them to turn down their security settings is probably unreasonable, so you may have to find a work around.
Let's say your site is www.acme.com and the iframe source is at www.myvendor.com.
IIRC, most domain-level security settings don't care about the hostname, so add a DNS CNAME to your zone file for myvendor.acme.com, pointed back to www.myvendor.com. Then, in your IFRAME, set the source using your hostname alias.
Another solution might be to have your Javascript set the src to a redirector script on your own server (and, thus, within your domain). Your script would then simply redirect the IFRAME to the "correct" URL with the same parameters.
If it suits you, you can communicate between sites with fragment identifiers. You can find an article here: http://tagneto.blogspot.com/2006/06/cross-domain-frame-communication-with.html
What BYK said. I think what's happening is you are GETting a URL that is too large for IE to handle. I notice you are trying to send variable named src, which is probably very long, over 4k. I ran into this problem before, and this was my code. Notice the comment about IE. Also notice it causes a problem with Firefox then, which is addressed in another comment.
var autoSaveFrame = window.frames['autosave'];
// try to create a temp form object to submit via post, as sending the browser to a very very long URL causes problems for the server and in IE with GET requests.
var host = document.location.host;
var protocol = document.location.protocol;
// Create a form
var f = autoSaveFrame.document.createElement("form");
// Add it to the document body
autoSaveFrame.document.body.appendChild(f);
// Add action and method attributes
f.action = protocol + '//' + host + "/autosave.php"; // firefox requires a COMPLETE url for some reason! Less a cryptic error results!
f.method = "POST"
var postInput = autoSaveFrame.document.createElement('input');
postInput.type = 'text'
postInput.name = 'post';
postInput.value = post;
f.appendChild(postInput);
//alert(f.elements['post'].value.length);
// Call the form's submit method
f.submit();
Based on Mike's answer, the easiest solution in your case would be to use "parameter hiding" to convert all GET parameters into a single URL.
The most scalable way would be for each 'folder' in the URL to consist of the parameter, then a comma, then the value. For example you would use these URLs in your app:
http://example.com/app/param,value/otherparam,othervalue
http://example.com/app/param,value/thirdparam,value3
Which would be the equivalent of these:
http://example.com/app?param=value&otherparam=othervalue
http://example.com/app?param=value&thirdparam=value3
This is pretty easy on Apache with .htaccess, but it looks like you're using IIS so I'll leave it up to you to research the exact implementation.
EDIT: just came back to this and realised it wouldn't be possible for you to implement the above on a different domain if you don't own it :p However, you can do it server-side like this:
Set up the above parameter-hiding on your own server as a special script (might not be necessary if IE doesn't mind GET from the same server).
In Javascript, build the static-looking URL from the various parameters.
Have the script on your server use the parameters and read the external URL and output it, i.e. get the content server-side. This question may help you with that.
So your iframe URL would be:
http://yoursite.com/app/param,value/otherparam,othervalue
And that page would read and display the URL:
http://externalsite.com/app?param=value&otherparam=othervalue
Try using an indirect method. Create a FORM. Set its action parameter to the base url you want to navigate. Set its method to POST. Set its target to your iframe and then create the necessary parameters as hidden inputs. Finally, submit the form. It should work since it works with POST.