Using a QR code securely - php

All,
I'm going to use a QR code from the following URL:
http://qrcode.kaywa.com/
I want to use the URL option so when someone scans it they are sent to the URL that I specified on the code. I want to have something like the following URL:
http://www.website.com/web-page/?type=uplights&action=checkout
Based on the variables in the URL I want to allow my user to insert some data.
Is there a way to secure this do that I know a user got to this URL from scanning the QR code instead of just typing that information into the URL?
Thanks!

Short Answer: Not directly.
QR codes were not designed to keep content stored within it secret. Someone could use a QR reader to scan your URL, store it and keep using it over and over again, without actually scanning it again.
One way we used to circumvent this issue was to encrypt our URL such that our own application (Based on ZXing) would be the only one capable of reading our QR code. It then sends the actual request with a nonce over a secure channel such that a replay attack would also be rendered useless (in case someone was sniffing outbound connections). All other readers see the encrypted URL which isn't of any use.
Other than that, there isn't another way of ensuring the user actually does scan your QR and doesn't type it out/paste it in.
The way we implemented this:
We stored the URL as http://www.website.com/app.php?<encrypted_string>. If someone read our URL a different QR decoder, they would be taken to our app.php page, which urged them to read the QR using our application.
Our app itself, on encountering that URL stripped off the encrypted query-string, decrypted it, and formed its own request to the right page. In PHP, you could execute that request at the server-end itself, so it is never visible to the user. You could use mcrypt as detailed here for encryption.

You can add a secret-ish parameter to the URL and not publish the URL with that parameter. But basically, no, you still won't know if someone didn't just type in that URL. (For example, I may have used the QR code, then cut and paste the URL in an email to a friend, and that friend may have typed it in.) But you'll know that they probably didn't just type it in.
QR codes are just easily reversible encodings for text. There's no magic there. So there are things you can do to make it less likely that someone typed in the URL, but you can never be certain.

Related

Security of fetching a url content in php

I am concerned about the safety of fetching content from unknown url in PHP.
We will basically use cURL to fetch html content from user provided url and look for Open Graph meta tags, to show the links as content cards.
Because the url is provided by the user, I am worried about the possibility of getting malicious code in the process.
I have another question: does curl_exec actually download the full file to the server? If yes then is it possible that viruses or malware be downloaded when using curl?
Using cURL is similar to using fopen() and fread() to fetch content from a file.
Safe or not, depends on what you're doing with the fetched content.
From your description, your server works as some kind of intermediary that extracts specific subcontent from a fetched HTML content.
Even if the fetched content contains malicious code, your server never executes it, so no harm will come to your server.
Additionally, because your server only extracts specific subcontent (Open Graph meta tags, as you say),
everything else that is not what you're looking for in the fetched content is ignored,
which means your users are automatically protected.
Thus, in my opinion, there is no need to worry.
Of course, this relies on the assumption that the content extraction process is sound.
Someone should take a look at it and confirm it.
does curl_exec actually download the full file to the server?
It depends on what you mean by "full file".
If you mean "the entire HTML content", then yes.
If you mean "including all the CSS and JS files that the feched HTML content may refer to", then no.
is it possible that viruses or malware be downloaded when using curl?
The answer is yes.
The fetched HTML content may contain malicious code, however, if you don't execute it, no harm will come to you.
Again, I'm assuming that your content extraction process is sound.
Short answer is file_get_contents is safe you retrieve data, even curl is. It is up to you what you do with that data.
Few Guidelines:
1. Never Run eval on that data.
2. Don't save it to database without filtering.
3. Don't even use file_get_contents or curl.
Use: get_meta_tags
array get_meta_tags ( string $filename [, bool $use_include_path = false ] )
// Example
$tags = get_meta_tags('http://www.example.com/');
You will have all meta tags parsed, filtered in an array.
you can use httpclient.class instead of file_get_content or curl. because it connect's the page through the socket.After download the data you can take the meta data using preg_match.
Expanding on the answer made by Ray Radin.
Tips on precautionary measures
He is correct that if you use sound a sound process to search the fetched resource there should be no problem in fetching whatever url is provided. Some examples here are:
Don't store the file in a public facing directory on your webserver. Then you expose yourself to this being executed.
Don't store it in a database, this might lead to a second order sql injection attack
In general, don't store anything from the resource you are requesting, if you have to do this use a specific whitelist of what you are searching for
Check the header information
Even though there is no foolprof way of validating what you are requesting with a specific url. There are ways you can make your life easier and prevent some potential issues.
For example a url might point to a large binary, large image file or something similar.
Make a HEAD request first to get the header information. Then look at the Content-type and Content-length headers to see if the content is a plain text html file
You should however not trust these since they can be spoofed. Doing this will hovewer make sure that even non-malicous content won't crash your script. Requesting image files is presumably something you don't want users to do.
Guzzle
I recommend using Guzzle to do your request since it is in my opinion provides some functionallity that should make this easier
It is safe but you will need to do a proper data check before using it. As you should with any data input anyway.

Encode the URL including its path in php

I want to encode the URL including its path in PHP.
For eg: As of now,my path is www.yoursite.com/code/results/show.php?u=10&n="tom".
I want to encode this URL so that user should not be able to see the
"/code/results/show.php?u=10&n="tom".
Why I need this because
I do not want to expose my server data location to user
Keep my server safe.
Thanks in advance.
You will need to look into .htaccess files, from there you can perform url rewrites that will take a url of (for example) www.yoursite.com/code/results/show.php?u=10&n=tom and instead output www.yoursite.com/results/10/tom.
If the u=10&n=tom is important, it can't be removed entirely from the URL, however it can be masked in the above way, the alternative is to do everything with POST, which is not a good way to go.
Take a look at this link: http://www.addedbytes.com/articles/for-beginners/url-rewriting-for-beginners/
best way to hide critical information is to keep it secret, instead just use a reference and get the information from the database.
in general its no good sign if security depends on how user are sending requests.
Sending it with POST would hide it, but not really... there are various ways to get and manipulate post-data.
the problem is not with url, URL should be used to only identify resource, if you want to hide something then it should not reach (be part of URL) client in the first place.

How to validate embed tag?

I'm allowing users to embed content from youtube, vimeo, scribd, flickr, slideshare, etc. and therefore i'm allowing them to paste the embed code in a textbox.
I'm having a hard time figuring out how to:
(a) validate that its indeed a correctly formed embed code and
(b) whether its not any malicious code that the user is trying to get my
system to display.
This is a php website.
I've used htmlpurifier in the past. There are some others, but this one worked the best for me. You can whitelist all allowed code constructs and make the html code standard compliant. It's a good first line of defense against XXS attacks.
The library is quite big and can slow down your code if you don't install it correctly, so read the install docs carefully.
We will be implementing a system where we ask the user to specify the direct URL and we go and subsequently fetch appropriate data from that page.

How can I prevent content from unauthorized views (php/js)

How can I prevent (unauthorized) people from reading a message on a website (e.g. by looking in the browser cache for the text/images)?**
It's a PUBLIC (!) site (means: no logins here!)
But:
the (secret) message is only shown for a certain time.
the message might be shown only if a passwort is given.
Problems:
In Opera for example page(=page contents/text) could be indexed by the browser and searched.
One idea was to create an image with the message ... but: Also images - even when a header "no cache" is send could be retrieved from FireFox's cache.
Also: Recreating the message from single characters as image does not work (at least I think so at the moment). I tried this method, but it makes output quite slow (writing this: I notice that I do not need to create the images at runtime, but could create images (of single letters) in advance and display/refer to them not by real, but pseudo random names in the HTML )
I also had the idea to output a encoded message (ROT13) (in HTML) but use JS .onload to decode the message immediately. Problem: If this code is in the HTML it could be recovered from the cache later on. At least if someone searches through the (Opera) cache the person would probably not think of entering search terms encoded.
Programming language is PHP.
You can't. What if someone takes a screenshot of this?
You could add the secret code to the page with javascript, after the page is loaded. You'd want to retrieve the secret code via AJAX, then write it to the page - that way, the code isn't cached in the HTML part of the source, and it isn't sitting in the javascript within the page's source code.
Content piped in with AJAX is pretty ephemeral, it won't be cached or otherwise recorded.
Since I don't know anything about your HTML or what (if any) javascript framework you might be using, I can't give you a code sample, but you should be able to work with the concept.
Realistically if it is sent to the client and displayed on screen then you can not prevent the message from being saved or stored on the client machine. Whatever you do to prevent that save could still be bypassed by a simple screenshot.
If you are not concerned about the person the message is targeted at saving said message then I think your best course of action would be to use Flash with Flash doing a call to the server to retrieve the message and display it. Another option may be to use javascript to perform some form of call (AJAX) to the server which then sends back the message and you alter the DOM to display the message. I don't think that would be cached but unless you use SSL it could be stored by intermediate proxies.

verifying a domain using php

I have a member area, where they can add their domains and it will be displayed in the profile page..but now I want to add a verification process, just like google web-masters does..where they need to upload a certain file and so..
please tell me whats the best way to do this ?
Thanks :)
Generate a token for each domain (sha-1 of domain or so), store it in your DB or what have you.
Generate a text-file containing the token on user request.
Ask the user to inform you to poll or poll every now and then to check the URL. This can easily be done by file_get_contents in PHP if fopen_wrappers are enabled.
The token is obviously compared to the token in your DB to make sure it wasn't just a random file present at a random domain..
Could be a good idea to check at some time interval if the file is still there, to keep someone from selling the domain but remain in control
It's not really black art as we can assume the user has access to its domain once any specific request which proves access can be fulfilled by the user. There's no real way to fool the system except doing some DNS-magic, or gaining entry to the webserver running on the domain, which is out of your control anyway.
Not sure if that's the best way, but I think Google does something like this:
get user's domain name (e.g. "http://example.com")
generate unique code and store in db
tell user where to upload the code (e.g. something like "/verification.txt")
after confirmation, make a HTTP request for the code ("http://example.com/verification.txt") from own server to the user's server
compare the code you received to the code in the db
You may want to generate consistently the same code for the same domain.
This question is convoluted. I think you need to spell out what you are looking for a little better.
EDIT #1:
Generate an md5 and give it to the user, tell them to put it on their domain and provide a URL to where it is. This could be in a txt file or anything.
Then read that file and check if the md5 string exists in there.
Actually I would come up with something slightly different than an md5. Maybe three of them, so that you reduce the chance they find it on some other domain and then give you that URL.
This can still be spoofed unless you nail down constraints, like it has to be a text file, the file must only contain the md5... etc.
Right now I can type in an md5 but it doesn't mean I control this website:
md5("i fooled you") = "0afb2d659b709f8ad499f4b87d9162f0"
But if I handed the URL to this answer, your system might accidentally think I have admin here.
I recommend creating a file and making them upload the file and give you the URL to it. But even that won't necessarily work because there are many sites where you can just upload something.
Maybe if it's a php encoded file that can execute? That's kind of a security flaw because I don't know if I would upload just anyone's PHP file. Typically if you don't have admin nobody is going to let you upload a php file that would work.
You might want to create a php call-home script but that's gonna be bad. People wouldn't use it.
Another way it could be done is:
Get the domain name
Generate a random code/string.
Sore this in your database
Make a meta tag and the random code in the content.
Use file get contents of the index page of the website.
Then search the page for the meta tag with the code sorted in the database.
If statement for success or unsuccessful.
The meta tag should look like this:
<meta name="site-verification" content="1010101010101010101010101010101010101010" />
Actually, just creating an md5-string for the domainname, letting the site owner put that in a meta-tag so you can check that would allready work fine ...

Categories