Hi I was wondering if it's possible to make sure only a specific device can validate a QR code?
For example I have a e ticket with a QR code. The QR code is going to be used to check people in to a specific ship they are going to board. Workers have a certain device which they can scan the QR codes with. This device only may validate these QR codes.
The reason I'm asking is that we don't want random users with random smartphones to scan the QR codes and trigger a URL that does the check-in and control when they aren't there and the date is not the date of the ticket and is not the device that should have validate the QR code.
I have no idea if there is a way to send a devices unique number along with the QR code or that the code on the specific URL can read out the information of the device ?
We are using PHP to create this web system. Has anybody done something like this before or does know how to deal with this issue ?
Looking forward on some information since I haven't found any useful information regarding issue's like these.
TL;DR: at its core, the issue isn't with QR codes, but rather with a severe design flaw in your application.
QR codes are standardized and meant to be somewhat ubiquitous. It's their ubiquity that has driven users' familiarity with them (how they look, what they do, how they can use them) and, thus, their adoption. There is no widely-available QR code standard that includes provisions for white-listing only certain devices to scan the resulting image. Even if there was, there would be numerous problems with this approach:
QR codes are somewhat permanent - they are usually affixed somewhere in the real world. If information about which devices were allowed to scan it could be embedded in the QR code itself, what would happen if you wanted to authorize a new device? It'd be financially and temporally impractical to replace every last QR just to allow this one new device.
QR codes can only store a finite amount of data - dependent on how many devices you'd actually want to be "authorized" to use a code, the authorization information could fill to a maximum capacity quite quickly.
Both the bullets above are a bit moot, as QR codes are evaluated by the scanning device - it would be somewhat trivial to patch over and bypass these restrictions on almost any device (similar to how you would never fully trust a validation happening on a client, and verify the data received on the server side).
It seems like you're trying to solve what appears to be a design flaw in your application by seeking to arbitrarily modify this widely-used standard to meet your specific use case.
Possible mitigations
Continue using a QR code tied to a specific URL, but only allow requests to change data/state when authenticated. Have your users navigate their mobile browser to the application in question and authenticate such that subsequent requests to the application (opening the URLs with the QRs) will be authorized correctly, and those without a valid authorization are greeted with a lovely 401 Unauthorized.
(It's somewhat concerning that you've implied both that (a) the state changes triggered by accessing these URLs are somewhat sensitive (in that you don't want random people scanning them), and (b) there's not already any system of authentication to prevent anyone, by either scanning the code or simply guessing the URL, from modifying this sensitive data on your server. I'd strongly suggest reviewing this design with someone from a security perspective to mitigate these risks before your data is tampered with by a third party.)
Change the design so the QR code being scanned is simply arbitrary textual data - similar to that of the numerical encoding accomplished with UPC barcodes - and have the authorized users leverage a custom client application that can take that arbitrary data and generate the proper API calls/URL opening(s) in the background.
Write your own standard similar to QR codes, and a corresponding client application to consume them.
As with most "is it possible?"-esque questions, the answer is usually "yes", and the variables are moreso things like time, funding, and knowledge (among others). It's unlikely in most all cases that you'd have a team with enough of all three to be able to pull this off in a reliable and secure manner, but if you did, your researchers might be able to write something completely new that could integrate this "authorization" as you wish to design it.
However, they'd still have to overcome the shortcomings I mentioned in my bullet points above for this to work, which would require supremely novel approaches to the problem usually only found in academic sectors and organizations with "skunkworks"-type departments. (Read: this is probably not what you want to do).
All in all, when using QR codes like this, the onus of security will be entirely on the receiving server/application. There is nothing in the QR code standard that will perform this authorization/authentication layer for you.
Aside from the three mitigations here, I'd also encourage you to take an even further step back to really evaluate whether QR codes are even the appropriate tool for this task.
Related
--LONG VERSION--
I made a super basic REST API to handle user account management (account creation, checking login credentials, etc.) that I will call from a Unity3D game, for which I plan to support mobile (mainly android).
Players would upload drawings that they'd make with a drawing tool that exists inside of the Unity game. I made that tool for the sole purpose of preventing the possibility of someone either uploading a screenshot of a drawing that they didn't draw themselves, or someone uploading a selfie or a pornographic photo (for which I cannot allow the possibility to happen, since my game is primarily targeted to children), and those drawings can be publicly viewed by other players.
--SHORT VERSION--
To store an uploaded drawing I would use a simple $_GET['base64'], but in order to prevent disallowed images from coming in, how can I assure that the request is coming from an official android build and not, say, some cURL or a reverse-engineered Unity project?
That's the whole question.
In the case of a WebGL build I could just block any web request that is not coming from the domain that the WebGL build is in, but in the case of the android build however, as far as I know the server can't really tell a request sent by an official android build from some request sent by a cURL. And I'm pretty sure that someone, with a bit of effort, can figure out how my REST API works. I have no idea of how to effectively secure it.
I'd like some suggestions, and if you think that my current approach is terrible (and it probably is) tell me how to improve on it or what to replace it with.
If you are serious about preventing unauthorized clients from sending images to your server the easiest way is to forget about dealing with images entirely.
Instead, I would have the clients and servers work with input data.
Have the client record the inputs the user makes to create their drawing (or, if that is too much, something that approximates the outcome of their inputs, such as sequences of line segments, colors, stroke widths, sticker ids, whatever your drawing system uses). As they draw the image, replace what they just drew with your system's representation of it so they can be certain of its appearance before sending.
Send, receive, and store the input data as needed
When the appearance of the drawing is needed, play back the recording to reproduce the drawing.
This is essentially how Jackbox does their drawing games, for instance.
Using this method, someone could try to reproduce a vague depiction of a selfie or pornography with your API of input data BUT if you do things like limit the size of the data, limit the fidelity of the colors, limit the resolution of the start and end of the line segments, etc, the capacity for these things to be reproduced is further and further reduced until it becomes unfeasible.
I have a dynamic page where it should take data from a db. So the approach I thought of was to create the dynamic page with this php code at the top
<?php $pid = $_GET["pid"]; ?>
Then later in the file it connects to the database and shows the correct content according to the page ID ($pid). So on the home page, I want to add the links to display the correct pages. For example, the data for the "Advertise" page is saved in the database in the row where the pid is 100. So I added the link to the "Advertise" page on the homepage like this:
Advertise</li>
So my question is, anyone can see the value that's send on the link and play around by changing the pid. Is there an easy way to mask this value, or a safer method to send the value to the page.php?
The general concept you're looking for is Access Control. You have a resource (in this case, a page and its content), and you want to control who can access it (users, groups, etc), and probably how they can access it as well (for example, read-only, read-and-write, write-but-only-on-the-first-Monday-of-the-month, etc).
Defining the problem
The first thing you need to decide is which resources you need access control for, and which you don't. It sounds to me like some of these pages are supposed to be "public access" (thus they are listed on some kind of index page), while others are supposed to be restricted in some way.
Secondly, you need to come up with an access policy - this can be informally described for a small project, but larger projects usually have some structured system for defining this policy. For each resource, your policy should answer questions like:
Do you have some kind of user account system, and you only want account holders (or certain types of account holders) to access it? Or, are you going to send links to email addresses, and want to limit access to just those people who have the link?
What kind of access should each user have? Read-only? Should they be able to change the content as well (if your system supports that)?
Are there any other types of restrictions on a users' access? Group membership? Do they need to pay before they get access? Are they only allowed access at specific times?
Implementing your policy
Once you've answered these questions, you can start to think about implementation. As it stands, I think you are mixing up access control with identification. Your pid identifies a page (page 100, for example), but it doesn't do anything to limit access. If your pages are identified with a predictable numbering scheme, anyone can easily modify the number in the request (this is true for both GET requests, such as when you type a URL into an address bar, and POST requests, such as when you submit a form).
To securely control access there needs to be a key, usually a string that is very difficult to guess, which is required before access is granted. In very simple systems, it is perfectly fine for this key to be directly inserted in the URL, provided you can still keep the key secret from unauthorized users. This is exactly how Google Drive's "get a link to share" feature works. More complex systems will use either a server-side session or an API key to control access - but in the end, it's still a secret, difficult-to-guess string that the client (user or user's browser) sends to the server along with their request for the resource.
You can think of identification like your street address, which uniquely identifies your house but is not, and is not meant to be, secret. Access control is the key to your house. Only you and the people you've given a key to can actually get inside your house. If your lock is high quality, it will be difficult to pick the lock.
Bringing it together
Writing code is easy, designing software is hard. Before you can determine the solution best for you, you need to think ahead about the ramifications of what you decide. For example, do you anticipate needing to "change the keys" to these pages in the future? If so, you'll have to give your authorized users (the ones that are still supposed to have access) the new key when that happens. A user-account system decouples page access control from page identification, so you can remove one user's access without affecting everyone else.
On the other hand, you also need to think about the nature of your audience. Maybe your users don't want to have to make accounts? This is something that is going to be very specific to your audience.
I get the sense that you're still fairly new to web development, and that you're learning on your own. The hardest part of learning on one's own is "learning what to learn" - Stack Overflow is too specific, and textbooks are too general. So, I'm going to leave you with a short glossary of concepts that seem most relevant to your current problem:
Access control. This is the name of the general problem that you're trying to solve with this question.
Secrecy vs obscurity. When it comes to security, secrecy == good, obscurity == bad.
Web content management system. You've probably heard of Wordpress, but there are tons of others. I'm not sure what your system is supposed to do, but a content management system might solve these problems for you.
Reinventing the wheel. Good in the classroom, bad in the real world.
How does HTTP work. Short but to the point. A lot of questions I see on SO stem from a fundamental misunderstanding of how websites actually work. A website isn't so much a single piece of software, as a conversation between two players - the client (e.g. the user and their browser), and the server. The client can only say something to the server via a request, and the server can only say something to the client via a response. Usually, this conversation consists of the client asking for some resource (an HTML web page, a Javascript file, etc), to which the server responds. The server can either say "here you go, I got it for you", or respond with some kind of error ("I can't find it", "you're not allowed to see that", "I'm too busy right now", "I'm not working properly right now", etc).
PHP The Right Way. Something I wish I had found when I first started learning web development and PHP, not seven years later ;-)
It is always safer to $_POST when you can, but if you have to use something in the query string, it is safer to use a hash or GUID rather than something that is so obviously an auto-incremental value. It makes it harder to guess what the IDs would be. There are other ways values can be past between pages ($_SESSIONs, cookies etc), but it is really about what you want to achieve.
Sending it to php is not an issue, should be fine.
What php does with it afterwards... that's how you secure.
First thing I'd do is make sure it's an integer.
$pid=(is_int($_GET['pid']))? $_GET['pid'] : 1; //1 is the default pid, change this to whatever you want.
Now that you know you're dealing with an integer, use $pid after that and you should be good to go.
I am an iOS developer & developed a web services app which has been live on App Store for a year. Now I decided to make this app available cross-platform - beginning with Android, for which I hired an Android Developer.
Until this hire, all the web related code & data (PHP / MySQL / XML) was managed & fetched by me alone - so I did not worry much about the security. But now, with addition of another developer I have following concern:
The app sends POST request which includes how many rows to fetch - then a PHP script gets that many rows from MySQL & returns them in a well formatted XML. My concern is that now the employee will also know about the whole process & although he will not have direct access to PHP scripts OR MySQL database, he can still misuse it in a number of ways. For example, he can create a URL on web browser with a POST request for 100000 rows even - which will let him have all the data in an XML.
What measures should be taken to counter this? (Yes, I can force a hard limit of 40 in above particular case, but it is not an ideal or generalized solution.)
BTW, I did an extensive google research on this topic & to my understanding, the above problem is known as "Semantic URL attack". But I was not able to figure out the right solution for it. Using "Sessions" is suggested, but according to my understanding "Sessions" is only helpful if we have password based user authentication - which is not the feature of my app.
Any help would be highly appreciated.
First you must be aware that if you have no protection and allow just anything, people will be able to do anything, as simple as that. So as I understand, you don't want to use the standard protections: i.e. users having login credentials, and using per-case defensive programming.
Okay, then one partial solution would be to compute a hash:
you want to query the server with the parameters P
you compute H=hash(P)
you send ?p=P&h=H to the server
your server receives ?p=P&h=H and computes H'=hash(P)
if H' != H, then the server denies an answer
You would have to compute the same deterministic hash function in php and in your mobile app, preferably a very complex one, mixing your own dark encrypting algorithms with md5, sha1, synchronized threads, etc.
If you worry about the attacker to repeat an old query with the right hash, you can make a more complex handshake: first send to the client a random number, which will be a part of the hash to compute. Or something based on the datetime, the ip, or whatever.
Of course if the attacker reverse engineers your code, he can find out the hash function, but it would take him some work at least. You can obfuscate your client's code if you want to make his job harder.
As a testimony, I have used this sort of technique against lame attackers on services which didn't require a registration. Unless the attacker is a pro and badly wants your private data, it works.
I am setting up a site using PHP and MySQL that is essentially just a web front-end to an existing database. Understandably my client is very keen to prevent anyone from being able to make a copy of the data in the database yet at the same time wants everything publicly available and even a "view all" link to display every record in the db.
Whilst I have put everything in place to prevent attacks such as SQL injection attacks, there is nothing to prevent anyone from viewing all the records as html and running some sort of script to parse this data back into another database. Even if I was to remove the "view all" link, someone could still, in theory, use an automated process to go through each record one by one and compile these into a new database, essentially pinching all the information.
Does anyone have any good tactics for preventing or even just detering this that they could share.
While there's nothing to stop a determined person from scraping publically available content, you can do a few basic things to mitigate the client's concerns:
Rate limit by user account, IP address, user agent, etc... - this means you restrict the amount of data a particular user group can download in a certain period of time. If you detect a large amount of data being transferred, you shut down the account or IP address.
Require JavaScript - to ensure the client has some resemblance of an interactive browser, rather than a barebones spider...
RIA - make your data available through a Rich Internet Application interface. JavaScript-based grids include ExtJs, YUI, Dojo, etc. Richer environments include Flash and Silverlight as 1kevgriff mentions.
Encode data as images. This is pretty intrusive to regular users, but you could encode some of your data tables or values as images instead of text, which would defeat most text parsers, but isn't foolproof of course.
robots.txt - to deny obvious web spiders, known robot user agents.
User-agent: *
Disallow: /
Use robot metatags. This would stop conforming spiders. This will prevent Google from indexing you for instance:
<meta name="robots" content="noindex,follow,noarchive">
There are different levels of deterrence and the first option is probably the least intrusive.
If the data is published, it's visible and accessible to everyone on the Internet. This includes the people you want to see it and the people you don't.
You can't have it both ways. You can make it so that data can only be visible with an account, and people will make accounts to slurp the data. You can make it so that the data can only be visible from approved IP addresses, and people will go through the steps to acquire approval before slurping it.
Yes, you can make it hard to get, but if you want it to be convenient for typical users you need to make it convenient for malicious ones as well.
There are few ways you can do it, although none are ideal.
Present the data as an image instead of HTML. This requires extra processing on the server side, but wouldn't be hard with the graphics libs in PHP. Alternatively, you could do this just for requests over a certain size (i.e. all).
Load a page shell, then retrieve the data through an AJAX call and insert it into the DOM. Use sessions to set a hash that must be passed back with the AJAX call as verification. The hash would only be valid for a certain length of time (i.e. 10 seconds). This is really just adding an extra step someone would have to jump through to get the data, but would prevent simple page scraping.
Try using Flash or Silverlight for your frontend.
While this can't stop someone if they're really determined, it would be more difficult. If you're loading your data through services, you can always use a secure connection to prevent middleman scraping.
force a reCAPTCHA every 10 page loads for each unique IP
There is really nothing you can do. You can try to look for an automated process going through your site, but they will win in the end.
Rule of thumb: If you want to keep something to yourself, keep it off the Internet.
Take your hands away from the keyboard and ask your client the reason why he wants the data to be visible but not be able to be scraped?
He's asking for two incongruent things and maybe having a discussion as to his reasoning will yield some fruit.
It may be that he really doesn't want it publicly accessible and you need to add authentication / authorization. Or he may decide that there is value in actually opening up an API. But you won't know until you ask.
I don't know why you'd deter this. The customer's offering the data.
Presumably they create value in some unique way that's not trivially reflected in the data.
Anyway.
You can check the browser, screen resolution and IP address to see if it's likely some kind of automated scraper.
Most things like cURL and wget -- unless carefully configured -- are pretty obviously not browsers.
Using something like Adobe Flex - a Flash application front end - would fix this.
Other than that, if you want it to be easy for users to access, it's easy for users to copy.
There's no easy solution for this. If the data is available publicly, then it can be scraped. The only thing you can do is make life more difficult for the scraper by making each entry slightly unique by adding/changing the HTML without affecting the layout. This would possibly make it more difficult for someone to harvest the data using regular expressions but it's still not a real solution and I would say that anyone determined enough would find a way to deal with it.
I would suggest telling your client that this is an unachievable task and getting on with the important parts of your work.
What about creating something akin to the bulletin board's troll protection... If a scrape is detected (perhaps a certain amount of accesses per minute from one IP, or a directed crawl that looks like a sitemap crawl), you can then start to present garbage data, like changing a couple of digits of the phone number or adding silly names to name fields.
Turn this off for google IPs!
Normally to screen-scrape a decent amount one has to make hundreds, thousands (and more) requests to your server. I suggest you read this related Stack Overflow question:
How do you stop scripters from slamming your website hundreds of times a second?
Use the fact that scrapers tend to load many pages in quick succession to detect scraping behaviours. Display a CAPTCHA for every n page loads over x seconds, and/or include an exponentially growing delay for each page load that becomes quite long when say tens of pages are being loaded each minute.
This way normal users will probably never see your CAPTCHA but scrapers will quickly hit the limit that forces them to solve CAPTCHAs.
My suggestion would be that this is illegal anyways so at least you have legal recourse if someone does scrape the website. So maybe the best thing to do would just to include a link to the original site and let people scrape away. The more they scrape the more of your links will appear around the Internet building up your pagerank more and more.
People who scrape usually aren't opposed to including a link to the original site since it builds a sort of rapport with the original author.
So my advice is to ask your boss whether this could actually be the best thing possible for the website's health.
About 4 years ago I used a php product called amember pro, it is a membership script which has plugins for lie 30 different payment processors, it was an easy way to set up an automated membership site where users would pay a payment and get access to a certain area.
The script used ioncube http://www.ioncube.com/sa_encoder.php to prevent non-paying users from using the script, it requered that you register the domain that the script would be used on, you were then given a key to enter into the file that would make the system/script work.
Now I am wanting to know how to do such a task, I know ioncube encoder just makes it hard to see the code, in the script I mention, they would just have a small section at the tp of 1 of the included pages that was encrypted and without that part of the code it would break and in addition if the owner of the script did not put you domain in the list and give you a valid key it would not work, also if you tried to use the script on a different domain it would not work.
I realize that somewhere in the encrypted code that is must of sent you key to there server and checked that it was valid for the domain name it is on, or possibly it did not even do that, maybe the key would just verify that it matched the domain the script was on, that more likely what it did.
Here is where the real question is, How would you make a script require the portion that is encrypted? If I made a script and had a small encrypted part at the top, it would seem a user would be able to easily just remove the encrypted part and figure out what the non encrypted part is doing and fix it to work. Any ideas?
fever has a similar model, you sign up, download the software (also PHP), then get an activation key. You can see how it works in the demo video (towards the end).
If you're giving away the source code, there's no way you can prevent someone with programming knowledge from patching out whatever copy protection / security you put in.
One thing I can think of is distributing a C/C++ compiled program or extension that the PHP app calls in to to verify the license. That compiled part could then phone home, etc. Even that could be easily circumvented though.
You can see some other ideas in these similar questions:
Code obfuscator for php?
Best solution to protect PHP code without encryption
Basically if you're giving away the code you're in an arms race with putting increasingly complex copy protection, which can always be broken in the end. You'll have to decide how much effort is worth it. I personally wouldn't invest much effort.
Not a perfect way of doing it, however you could use an encoder to hide the code and make it call a page on your server that returns a value that is difficult to forge. It would be server intense, but could do what you want. You would want to do something where time was involved. Updating the code so often.
I have seen it done multiple ways. Just about any software method you think of can be bypassed if somebody is interested enough to work at it. We use ioncube to encrypt our non-hosted products and back it up with a USB hardware dongle. Can it be cracked? Yes. But, people are basically honest. I think the thing to do to keep people paying for the script is to make it a pain to crack and release frequent updates with new features that people won't want to wait for. If your price isn't too high, people will just decide to pay for it instead of cracking.