Reputation: 5379
Is it possible to password protect (from website users) certain directories on a server? It doesn't have to be secure as it's only meant to prevent learners from downloading/accessing materials from other courses. The learners are not very tech-savvy so it's not a big deal.
Say I have directories with 3 courses: /course1 /course2 /course3
and I'd like each directory to have its own password so I can email learners doing course1 its url and password. How would I do it? I have a very limited access to the server so client side is the only option.
Upvotes: 3
Views: 1628
Reputation: 14875
Thinking about Maximillian Laumeister’s idea I came up with this. This may not be a perfect solution but should work.
You store all resources on the server encrypted, encoded as base64 in plain text files. Separated by a comma you prepend the desired mime type. E.g.
main
: (CryptoJS.AES.encrypt('<a href="http://localhost:8080/_/more">Read more</a>', "hello").toString();
)
text/html;U2FsdGVkX19Tdq6V7swK/7NgnwR8JgZ1dYZEkfT9hx+QKzFrpyqKeuo0Tv25ozYkAxIIt65G9DKmOYU6tmZ0Dp/I4BuopQ/3xHClB+K+BX8=
more
: (CryptoJS.AES.encrypt('<h1>More</h1><p>Lorem ipsum dolor sit</p>', "hello").toString();
)
text/html;U2FsdGVkX19GdZ+SRQ9vM2Amiyu0OqOOSX7X5IOCcLfHMpHHgI0h/mxS8iuUggfqmFBN+yXy53z445ZW1mAlHQ==
In hyperlinks you have to place something in URLs (_/
) causing a 404 which can be removed later on and you have to specify the protocol including the server. This is the only way the script can intercept the request, stop it, request the correct URL and decode the response. (The 404 is needed because browsers will otherwise download the specified file directly and will not call the load
event handlers.)
You then create an index.html
page which contains an iframe and requests the user to enter a password which is then kept in some scope so that no XSS attack could retrieve the value.
<html>
<head>
<meta charset="utf8">
</head>
<body>
<iframe id="theIframe"></iframe>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script src="script.js"></script>
</body>
</html>
This allows you to request an URL, decode the received base64 content and try to decrypt it with the given password. You would then set the decrypted content as the iframe’s content via a data URL.
(function(){
var iframe = document.getElementById("theIframe");
var password = prompt("Enter the password!");
var allowEvent = true;
function presentURL(url){
allowEvent = false;
var req = new XMLHttpRequest();
req.addEventListener("load", function(){
var splitters = this.responseText.split(";", 2);
var type = splitters[0];
var encrypted = splitters[1];
var decrypted = CryptoJS.AES.decrypt(encrypted, password).toString(CryptoJS.enc.Utf8); //Decrypt
var data = window.btoa(decrypted); //Encode the decrypted data into base64
iframe.src = "data:" + type + ";base64," + data;
});
req.open("GET", url);
req.send();
}
presentURL("/main");
iframe.addEventListener("load", function(e){
e.preventDefault();
if (allowEvent){
iframe.contentWindow.stop();
//remove the 404 cause and call presentURL
presentURL(iframe.contentWindow.location.href.replace(/_\//, ""));
}
else {
allowEvent = true;
}
});
})();
The above example uses CryptoJS and may not work across browsers!
This code actually works!
Upvotes: 4
Reputation: 2830
If you care zero about security this could be done in a few ways. Here is a rough example to get you thinking about the logic you may need for this;
Consider the following code:
var password = '12345678';
function showBody() {
// Password matches?
if ( document.getElementById( 'code' ).value == password ) {
// Show secret stuff and hide password box
document.getElementById( 'container' ).style.display = 'block';
document.getElementById( 'code' ).style.display = 'none';
}
}
document.body.onload = function () {
// Hide the secret stuff
document.getElementById( 'container' ).style.display = 'none';
// Create a password box
var input = document.createElement( 'input' );
input.setAttribute( 'type', 'password' );
input.setAttribute( 'id', 'code' );
// Append the password box
document.body.appendChild( input );
// Listen for the password
document.addEventListener( 'keyup', showBody, false );
}
<body>
<div id = 'container'>
I am hidden
</div>
</body>
Keep in mind there is more than one way to do this. This is simply an example so you can get started writing your code and get the general idea of how the logic for this type of thing could be done. It is very insecure and you should definitely consider other solutions from the server.
Upvotes: -1