I am designing a web site in which users solve puzzles as quickly as they can. JavaScript is used to time each puzzle, and the number of milliseconds is sent to the server via AJAX when the puzzle is completed. How can I ensure that the time received by the server was not forged by the user?
我正在设计一个网站,让用户尽可能快地解决难题。JavaScript用于计时每个难题,当难题完成时,通过AJAX将毫秒数发送给服务器。如何确保服务器接收到的时间不是用户伪造的?
I don't think a session-based authenticity token (the kind used for forms in Rails) is sufficient because I need to authenticate the source of a value, not just the legitimacy of the request.
我认为基于会话的真实性令牌(Rails中用于表单的那种)是不够的,因为我需要对值的来源进行身份验证,而不仅仅是请求的合法性。
Is there a way to cryptographically sign the request? I can't think of anything that couldn't be duplicated by a hacker. Is any JavaScript, by its exposed, client-side nature, subject to tampering? Am I going to have to use something that gets compiled, like Flash? (Yikes.) Or is there some way to hide a secret key? Or something else I haven't thought of?
是否有一种方法可以对请求进行加密签名?我想不出有什么东西是黑客无法复制的。任何JavaScript,从其公开的客户端特性来看,是否会受到篡改?我需要使用一些编译过的东西吗,比如Flash?(呀!)或者有什么办法隐藏秘密钥匙?或者其他我没想过的事情?
Update: To clarify, I don't want to penalize people with slow network connections (and network speed should be considered inconsistent), so the timing needs to be 100% client-side (the timer starts only when we know the user can see the puzzle). Also, there is money involved so no amount of "trusting the user" is acceptable.
更新:为了澄清,我不想惩罚网速慢的人(网速应该被认为是不一致的),所以时间需要100%客户端(只有当我们知道用户能看到拼图时,计时器才会开始)。此外,还涉及资金,因此不允许“信任用户”。
15 个解决方案
#1
9
This approach obviously makes assumptions and is not invincible. All calculations are done on the client, and the server does some background checks to find out if the request could have been forged. Like any other client-based approach, this is not deterministic but makes it very hard for a lying client.
这种方法显然会做出假设,而且不是不可战胜的。所有计算都在客户机上完成,服务器进行一些背景检查,以确定请求是否伪造。与其他任何基于客户端的方法一样,这不是确定性的,但对于撒谎的客户来说,这非常困难。
The main assumption is that long-lived HTTP connections are much faster for transmitting data, even negligible in some cases depending on the application context. It is used in most online trading systems as stock prices can change multiple times within a second, and this is the fastest way to transmit current price to users. You can read up more about HTTP Streaming or Comet here.
主要假设是,长生命周期的HTTP连接传输数据的速度要快得多,甚至在某些情况下可以忽略,这取决于应用程序上下文。大多数在线交易系统都使用它,因为股价可以在一秒钟内多次变化,这是将当前价格传递给用户的最快方式。您可以在这里阅读更多关于HTTP流或Comet的信息。
Start by creating a full-duplex ajax connection between the client and server. The server has a dedicated line to talk to the client, and the client can obviously talk to the server. The server sends the puzzle, and other messages to the client on this dedicated line. The client is supposed to confirm the receipt of each message to the server along with its local timestamp.
首先创建客户端和服务器之间的全双工ajax连接。服务器有专线与客户端对话,客户端显然可以与服务器对话。服务器将难题和其他消息发送到此专用行的客户端。客户端应该确认每个消息的接收情况以及服务器的本地时间戳。
On the server generate random tokens (could be just distinct integers) after the puzzle has been sent, record the time when each token was generated, and pass it over to the client. The client sees the message, and is supposed to immediately relay this token back along with it's local time of receipt. To make it unpredictable for the client, generate these server tokens at random intervals, say between 1
and n
ms.
在服务器上生成随机令牌(可能只是不同的整数),然后记录生成每个令牌的时间,并将其传递给客户端。客户端看到消息,并且应该立即将此令牌转发给本地时间的收据。为了使客户端不可预测,在1和n ms之间随机生成这些服务器令牌。
There would be three types of messages that the client sends to the server:
客户端会向服务器发送三种类型的消息:
PUZZLE_RECEIVED
TOKEN_RECEIVED
PUZZLE_COMPLETED
And two types of messages that the server sends to the client:
以及服务器发送给客户的两种消息:
PUZZLE_SENT
TOKEN_SENT
There could be a lot of time variation in the messages send from the client to the server, but much lesser in the other direction (and that's a very fair assumption, hey - we have to start somewhere).
从客户端发送到服务器的消息可能有很多时间上的差异,但在另一个方向上的差异要小得多(这是一个非常合理的假设,嘿——我们必须从某个地方开始)。
Now when the server receives a receipt to a message it sent, record the client time contained in that message. Since the token was also relayed back in this message, we can match it with the corresponding token on the server. At the end of the puzzle, the client sends a PUZZLE_COMPLETED
message with local time to the server. The time to complete the puzzle would be:
现在,当服务器接收到它发送的消息的收据时,记录该消息中包含的客户端时间。由于该令牌也在此消息中被转发,所以我们可以将它与服务器上的相应令牌进行匹配。在难题结束时,客户端向服务器发送带有本地时间的PUZZLE_COMPLETED消息。完成这个难题的时间是:
PUZZLE_COMPLETED.time - PUZZLE_RECEIVED.time
Then double check by calculating the time difference in each message's sent vs received times.
然后通过计算每个消息的发送时间和接收时间的时间差来再次检查。
PUZZLE_RECEIVED.time - PUZZLE_SENT.time
TOKEN_RECEIVED.time - TOKEN_SENT.time
A high variance in these times implies that the response could have been forged. Besides simple variance, there is lots of statistical analysis you can do on this data to look for odd patterns.
在这些时间内的高方差意味着响应可能是伪造的。除了简单的方差,您还可以对这些数据进行大量的统计分析,以查找奇数模式。
#2
12
You can't guarantee the security of the timings cryptographically, because the client's browser can't do secure computation. Any means for encrypting to/from the server could be bypassed by adjusting the actual timings.
您不能以密码方式保证计时的安全性,因为客户机的浏览器不能进行安全计算。任何对服务器进行加密的方法都可以通过调整实际的时间来绕过。
And timing on the server doesn't work, either - if you don't take account of latency in the round-trip-time, users with lower latency connections will have an advantage; if you do, users could thwart the compensation phase by adding extra latency there and then removing it later.
服务器上的时间安排也不起作用——如果不考虑往返时间中的延迟,具有较低延迟连接的用户将具有优势;如果您这样做,用户可以在补偿阶段添加额外的延迟,然后在稍后删除它。
You can, of course make it difficult for the users to modify this, but security by obscurity is an unsustainable policy anyway.
当然,您可以让用户很难修改它,但是不透明的安全性是不可持续的策略。
So it comes down to either trusting your users somewhat (a reasonable assumption, most of the time) and designing the game so it's not trivial to circumvent the timings.
因此,它可以归结为信任您的用户(在大多数情况下是合理的假设)和设计游戏,以避免浪费时间。
#3
8
Even a compiled application could be forged. If the user changes their system clock halfway through timing, your application will report an incorrect time to the server. The only way to get an accurate upper-bound on the time it takes them is to start timing on the server when the puzzle is given to them, and to stop timing when they supply the answer.
即使编译好的应用程序也可以伪造。如果用户在计时过程中更改了系统时钟,您的应用程序将向服务器报告错误的时间。要在所需的时间上获得准确的上限,唯一的方法是在给他们难题时在服务器上开始计时,并在他们提供答案时停止计时。
As others have pointed out you can minimise the effect that slow connections have by making the load of the puzzle as small as possible. Load the entire page and "game engine" first, and then use an asynchronous request to load the puzzle itself (which should be a small amount of data) to level the playing field as much as possible.
正如其他人指出的那样,你可以通过使拼图的负载尽可能小来最小化慢速连接的影响。首先加载整个页面和“游戏引擎”,然后使用一个异步请求来加载拼图本身(应该是少量的数据),以尽可能地使游戏更加公平。
Unfortunately you can't do latency compensation as this would be open to tampering. However, on a connection that's not being used for anything else, the latency for a request like this would be greatly overshadowed by the time it takes a human to solve a puzzle, I don't think it will be a big deal.
不幸的是,您不能执行延迟补偿,因为这将会被篡改。然而,在一个没有被用于任何其他用途的连接上,像这样的请求的延迟将被人类解决难题所需的时间所掩盖,我认为这不是什么大问题。
(Reasoning: 200ms is considered very bad lag, and that's the average human reaction time. The shortest possible "puzzle" for a human to complete would be a visual reaction speed test, in which case bad lag would have a 100% markup on their results. So as a timing solution this is 2-OPT. Any puzzle more complex will be impacted less by lag.)
(推理:200ms被认为是非常糟糕的滞后,这是人类的平均反应时间。人类完成的最短的“谜题”可能是视觉反应速度测试,在这种情况下,糟糕的滞后将在他们的结果上有100%的标记。作为一个定时解决方案,这是2-OPT。任何更复杂的难题都会因滞后而减少。
I would also put a banner on the page saying to not use the internet connection for anything else while playing for the best possible speeds, possibly linking to a speed / latency tester.
我还会在页面上放一个横幅,上面写着在播放尽可能快的速度时不要使用互联网连接,可能会链接到速度/延迟测试器。
#4
4
It is impossible to start and stop the timer at the client-side without fear of manipulation...
在客户端启动和停止计时器是不可能的,而不必担心操作……
Anything you perform at the client can be altered / stopped / bypassed..
您在客户端执行的任何操作都可以更改/停止/绕过。
encrypting/decrypting at the client is also not safe since they can alter the info before the encryption occurs..
在客户端进行加密/解密也不安全,因为他们可以在加密发生之前修改信息。
Since it involves money, the users can not be trusted..
由于涉及到金钱,用户是不可信的。
The timing has to start at the server, and it has to stop at the server..
时间必须从服务器开始,它必须在服务器停止。
Use ajax to start the timer at the server only if the puzzle contents return with the result of the ajax call. do not load the puzzle and then sent an ajax request as this could be hijacked and delayed while they review the puzzle...
只有当难题内容返回到ajax调用的结果时,才使用ajax在服务器上启动计时器。不要加载迷惑,然后发送一个ajax请求,因为这可能会被劫持和延迟,因为在他们检查迷惑的时候……
..
. .
#5
3
Depending on the server side implementation you have, you could put the timing functionality on the server side. Record the time that the webpage request was made (you could put that into a database if you liked) and then when the answer is received get the current time and perform some arithmetic to get the duration of the answer. You could store the time in the session object if you liked instead of the database as well although I don't know too much about its integrity in there.
根据您所拥有的服务器端实现,您可以将计时功能放在服务器端。记录完成网页请求的时间(如果您愿意,可以将其放入数据库中),然后在接收到答案时获取当前时间并执行一些运算以获得答案的持续时间。您可以将时间存储在会话对象中,如果您喜欢,而不是数据库,尽管我不太了解它的完整性。
#6
3
You have to use server-side time here. Here is how I would do it:
这里必须使用服务器端时间。我是这样做的:
Make an AJAX request on document ready to ping the server. When server-side code receives the ping, store the server-side time as a session variable (making sure the variable does not already exist). When they finish the quiz, take the server-side time again and compare it with the session variable to determine their duration. Remove the session variable.
对准备ping服务器的文档发出AJAX请求。当服务器端代码接收到ping时,将服务器端时间存储为会话变量(确保该变量不存在)。当他们完成测试时,再次使用服务器端时间,并与会话变量进行比较,以确定测试的持续时间。删除会话变量。
Why this works:
为何如此:
- You do not start the timer before they see the quiz
- 你不能在他们看到测验之前就开始计时
- The network delay is factored in, because the timer does not start until the AJAX request comes in (if they have a slow connection, the AJAX request will be slow)
- 考虑到网络延迟,因为计时器直到AJAX请求进入才会启动(如果它们的连接很慢,那么AJAX请求就会很慢)
- Ping is not spoofable because you make sure the session variable does not exist before storing
- Ping是不可欺骗的,因为您要确保在存储之前会话变量不存在
EDIT: I wanted to add that you could continue to keep client-side time, and include it in the final post. Then you can compare it with your server-side calculated time. If they are reasonably close, then you can trust the client time.
编辑:我想补充一点,您可以继续保持客户端时间,并将其包含在最终的帖子中。然后您可以将其与服务器端计算的时间进行比较。如果它们非常接近,那么您可以信任客户的时间。
#7
2
You asked a bunch of questions in your original question, I'm only going to answer one of them:
你问了很多问题,我只回答其中一个
Am I going to have to use something that gets compiled, like Flash? (Yikes.)
我需要使用一些编译过的东西吗,比如Flash?(呀!)
Yes. Given your criteria: 1) 100% accurate, and 2) No possibility of user interference, you have to use a compiled binary.
是的。给定您的标准:1)100%准确,2)不存在用户干扰,您必须使用编译后的二进制文件。
Doesn't have to be flash though - I'd suggest a java applet if the thought of Flash makes you say "Yikes".
不过不一定非得是flash——如果一想到flash你就会说“Yikes”,我建议你使用java applet。
#8
2
-- Edit:
——编辑:
This solution is somewhat flawed, as pointed out by ZoFrex below.
正如下面ZoFrex指出的,这个解决方案有些缺陷。
-- Old:
——老:
Here is a way (but you'll need to do some profiling).
这里有一个方法(但您需要做一些分析)。
Send down a series of "problems" for the JavaScript to solve, while they are playing the puzzle. Previously, I've sufficiently-sized number N such that it is the result of: prime1 * prime2. This forces the client to factor the number (you can get code to do this in JavaScript) and this will take time (this is where profiling clients comes in, and sending down appropriately-sized primes [obviously, this opens you to degradation-attacks, but nevertheless]).
在他们玩拼图游戏的时候,给JavaScript发送一系列“问题”来解决。之前,我有一个足够大的数字N,这样的结果是:prime1 * prime2。这将迫使客户端对数字进行分解(您可以用JavaScript编写代码来实现这一点),这将需要时间(这就是分析客户端进入的地方,并发送适当大小的质数(显然,这将导致降级攻击,但无论如何)。
Then, you just send down say, 500, of these prime-problems (or another type), and let the JavaScript solve them in the background. It will generate a list of solutions, and when you send the completed value, you also send this list. From the total count of answers supplied, you can determine how long they spent on the puzzle.
然后,你只需发送500个这样的主要问题(或其他类型),让JavaScript在后台解决它们。它将生成一个解决方案列表,当您发送完成的值时,您也将发送这个列表。从所提供的答案总数中,您可以确定他们在这个难题上花费了多长时间。
Cons:
缺点:
- Requires profiling to determine capabilities of various clients (and hence difficulty of problems)
- 要求概要分析以确定各种客户机的功能(因此存在问题)
- Can be downgrade-attacked
- 可以downgrade-attacked
- Slightly complicated
- 稍微复杂的
- JavaScript computation may interrupt general puzzle-solving
- JavaScript计算可能会中断一般的解谜
- Possible to write a bot to get solve problems faster than JS
- 可以编写一个比JS更快的机器人来解决问题
Pros:
优点:
- Calculations must be done in order to submit the form
- 为了提交表格,必须进行计算
- If implemented correctly, will prevent all but non-trivial attacks
- 如果实现正确,将避免所有的攻击
Clearly, it's attackable, (all proposed answers are), but I think it's reasonable. At least, it would be fun to work on :)
显然,这是可以攻击的(所有提议的答案都是),但我认为这是合理的。至少,它将是有趣的工作:)
In the end, though, you need to actually install a client-side system with a bit more security. And do note that Flash certainly is not this; it's trivial to decompile. Infact, there was an IQ test here in Australia once, and it was controlled via a Flash app that was done LIVE on television. Of course, the winner was a computer programmer, I wonder why :P
不过,最终您需要实际安装一个具有更多安全性的客户端系统。请注意,Flash肯定不是这个;反编译是微不足道的。事实上,澳大利亚曾经有过一次IQ测试,它是通过在电视上直播的Flash应用来控制的。当然,获胜者是一个计算机程序员,我想知道为什么:P
-- Edit:
——编辑:
OP, Also, I linked it in a comment to this post, but just incase you miss it, you are kind of interested in the Hashcash, which is the aim to show that a client has completed some amount of 'Work'. Even if my implementation isn't suitable, you may find a review of that field fruitful.
OP,同样,我在一个评论中把它链接到这篇文章,但是如果你错过了,你会对Hashcash感兴趣,它的目的是显示客户已经完成了一些“工作”。即使我的实现不合适,您可能会发现对该领域的审查结果很有成效。
#9
2
It's a tricky problem because it's fundamentally unsolvable, so you need to work around the tradeoffs to do your best. There've been several good points made on the technical side including: (a) don't waste your time thinking compiling to Flash, Windows, Silverlight, JVM, or anything will actually help, (b) first transmit the encrypted real puzzle payload, then as the actual bottleneck transmit the key alone, (c) the latency even on 56k of sending a couple hundred bytes is negligible compared to human reaction time.
这是一个棘手的问题,因为它从根本上来说是无法解决的,所以你需要围绕权衡来尽你最大的努力。有几个好点的技术方面,包括:(a)别浪费时间思考编译Flash,窗户,Silverlight,JVM,或者任何会帮助,(b)首先传输加密的真正难题有效载荷,当实际传输的关键瓶颈,(c)即使在56 k的延迟发送几百字节是人类反应时间相比可以忽略不计。
One thing I haven't seen mentioned is this:
有一件事我没有提到:
Use after-the-fact auditing and tracking of users. This is how real casinos work. This is, I am told, a big part of how PayPal made their money. In both cases, rather than doing a lot of before-the-fact security, they keep very close tabs on everything about their players, use a lot of technology (statistics, pattern detection, etc) to flag suspicious players and they investigate. In both casinos and PayPal, you can't get your money right away. You have to cash in your chips or wait for the money to make it out of the PayPal system into your real bank. Your system should work the same way-- they can't actually get the money for at least a few days at minimum (longer if you are unable to set up a sufficiently speedy auditing system), giving you time to potentially impound their winnings. You have a lawyer, right? Also, casinos and PayPal know your real life identity (a must for dealing in money) so they can go after you legally-- or more importantly, deter would-be attackers since they could go after them legally.
使用事后审计和用户跟踪。这就是真正的赌场的运作方式。我听说,这是贝宝赚钱的一个重要原因。在这两种情况下,他们不会做很多事前安全工作,而是密切关注玩家的一切,使用大量的技术(统计数据、模式检测等)来标记可疑的玩家,并进行调查。在赌场和贝宝,你不能马上拿到钱。你必须把你的芯片换成现金,或者等到钱从贝宝系统转到你真正的银行。您的系统应该以同样的方式工作——他们实际上至少不能获得几天的资金(如果您无法建立一个足够快速的审计系统,则需要更长的时间),从而让您有时间没收他们的奖金。你有律师,对吧?此外,赌场和贝宝知道你的真实身份(在金钱交易中必须具备的身份),这样他们就可以合法地追捕你——或者更重要的是,阻止潜在的攻击者,因为他们可以合法地追捕他们。
Combined with the other tips, this may be sufficient to eliminate cheating entirely.
结合其他技巧,这可能足以完全消除作弊。
If you find it is not, make your goal not to totally eliminate cheating but to keep it to an acceptable level. Kind of like having 99.99% uptime. Yes, as one poster said, if even one person can compromise it everyone is screwed, but with a good auditing system the attacker won't be able to consistently cheat. If they can cheat 1 in 1000 times if they're lucky and they find they can't cheat more than once or twice before being caught, it won't be a problem since very few will cheat and any given honest user will have an extremely low chance of being affected by an extremely small amount of cheating. It'll be imperceptible. If you ever have a real cheating occurence that hurts an honest user, go out of your way to make the honest user feel satisfied with the outcome to a degree out of proportion to the value of that single customer. That way everyone will be confident in your security. They know they don't have to worry about anything.
如果你发现它不是,让你的目标不是完全消除作弊,而是保持一个可接受的水平。有点像99.99%的正常运行时间。是的,就像一张海报说的那样,如果一个人可以妥协,那么每个人都完蛋了,但是有了一个好的审计系统,攻击者就不会一直作弊了。如果他们能欺骗1 1000年*如果他们幸运,他们发现他们不能欺骗一次或两次以上被抓之前,它不会是一个问题,因为很少会欺骗和任何诚实的用户将受到影响的几率极低极少量的作弊。它会听不清。如果你真的有过欺骗行为,伤害了一个诚实的用户,那就尽力让诚实的用户在一定程度上对结果感到满意。这样每个人都会对你的安全充满信心。他们知道他们什么都不用担心。
People problems are not always solvable with technology solutions alone. You sometimes need to use people solutions. (The technology can help those people solutions work a lot better though.)
人的问题并不总是单靠技术解决的。你有时需要使用人员解决方案。(不过,这项技术可以帮助这些人更好地解决问题。)
#10
1
excuse me but why you can't use the time on the server? the time when you recieve the response will be the one which you use to calculate the score.
对不起,你为什么不能在服务器上使用时间?您收到响应的时间将是您用来计算分数的时间。
#11
1
As several others have pointed out:
正如其他几个人指出的那样:
- You must use server time, because client time is vulnerable to manipulation.
- 您必须使用服务器时间,因为客户机时间容易被操纵。
- Checking the time on the server will potentially penalize people with slow network connections, or people that are far away.
- 检查服务器上的时间可能会惩罚网络连接缓慢的人,或者远程的人。
The answer to the problem is to use a time synchronization protocol between the client and the server similar to the protocol that NTP uses. Working together, the client and the server determine the amount of delay caused by network latency. This is then factored into the times given to each user.
问题的答案是在客户端和服务器之间使用与NTP使用的协议类似的时间同步协议。在一起工作时,客户机和服务器决定网络延迟所导致的延迟量。然后将其分解为给每个用户的时间。
NTP's algorithms are complicated and have been developed over years. But a simple approach is below; I think that the protocol should work, but you may wish to test it.
NTP算法是复杂的,并且已经发展多年。下面是一个简单的方法;我认为协议应该有效,但是您可能希望测试它。
Have the client measure the round-trip time with two successive HTTP XMLRPC pings. Each ping returns a different nonce. The second ping requires the nonce from the first ping, which assures that they are sequential. The puzzle time starts when the second HTTP ping is sent from the client. The server timestamps each request and assumes that the puzzle is displayed 1/2 way between the receipt of the first and the second request.
让客户端使用两个连续的HTTP XMLRPC ping来度量往返时间。每个ping返回一个不同的nonce。第二个ping需要来自第一个ping的nonce,这确保它们是连续的。当从客户端发送第二个HTTP ping时,问题开始了。服务器为每个请求设置时间戳,并假定迷惑显示在收到第一个请求和第二个请求之间的半路上。
When the puzzle is finished the client pings twice again, following the same protocol as before. The server knows when it receives each request and it knows the time delta. Now take half the time delta and subtract that from when the first ping of the second set is received. That can be safely assumed to be the time that the puzzle was completed.
当这个难题再次完成时,客户端会重复两次,遵循和以前一样的协议。服务器知道何时接收每个请求,并知道时间增量。现在取一半的时间增量,减去接收到第二组第一个ping信号时的时间增量。可以有把握地假定这是完成这个谜题的时间。
#12
0
there is a very fast implementation of cryptography in js here
在js中有一个非常快速的加密实现
http://crypto.stanford.edu/sjcl/
http://crypto.stanford.edu/sjcl/
it allows public / private key encryption all on the client and I think you can adapt it to encrypt the Ajax communication between your server and the client browser
它允许在客户机上进行公钥/私钥加密,我认为您可以对它进行调整,以便对服务器和客户机浏览器之间的Ajax通信进行加密
here is a detailed explanation, which you can adapt to your needs http://crypto.stanford.edu/sjcl/#usage
这里有一个详细的解释,您可以根据自己的需要(http://crypto.stanford.edu/sjcl/#usage)
#13
0
Just a quick thought: why don't you use an iFrame to include the game and it's javascripts and let them reside on the server you have your server side implementation running. Any ajax request should then be sent by the same IP as your server side IP is which would solve the problem of identifying the source. Of course you have to take further measures but already gained a lot of confidence in your "client" side requests. Remember the windowsLive services login and many more like it are based on javascript and the usage of iFrames and are considered secure enough.
简单地想一下:为什么不使用iFrame来包含这个游戏,它是javascript,让它们驻留在服务器上,让服务器端实现运行。然后,任何ajax请求都应该由与服务器端IP相同的IP发送,这将解决标识源的问题。当然,你必须采取进一步的措施,但你已经对“客户”方面的要求有了很大的信心。请记住,windowsLive服务登录以及其他类似的功能都是基于javascript和iframe的使用,并被认为足够安全。
#14
0
I do not think there is a perfect solution. Here is an alternative that makes it harder for cheater but at the same time an unlucky honest solver may lose out.
我认为没有完美的解决方案。这是另一种选择,它使骗子更难,但同时一个不幸的诚实的解决者可能会失去。
Get many samples of roundtrip time measurements from each specific devices/location/other combination apriori for each user based on their other interaction with your site. You will also have these measurements for the entire population. You could also be very subtle get the timestamps for when a particular DNS lookup happened from their ISP's resolver (random hostname and you host the authoritative DNS server for that domain).
根据每个用户与站点的其他交互,从每个特定的设备/位置/其他组合中获取许多往返时间度量的示例。你还可以对整个群体进行测量。您还可以非常巧妙地从其ISP解析器(随机主机名,并托管该域的权威DNS服务器)获取特定DNS查找发生的时间戳。
Once you have this, perform all measurements on the server side (puzzle returned to user, solution received) and subtract out the network time based on previous observations.
一旦您有了这个,在服务器端执行所有的度量(难题返回给用户,解决方案接收),并根据以前的观察减去网络时间。
Note that even in other solutions you have server load, client load (slow processor, etc.), etc that affect timing.
注意,即使在其他解决方案中,服务器负载、客户端负载(慢处理器等)等也会影响时间。
Make sure you have XSRF protection on puzzle submission page :)
确保您在拼图提交页面上有XSRF保护:)
#15
-4
The way I would do this is that when the server sends the puzzle to the client, the current time is stored in a session. This ensures that the timing starts immediately after the puzzle has been sent. After the puzzle has been completed, and is sent to the server to check if the puzzle was done right, the server again checks the time and does a comparison.
我这样做的方法是,当服务器将难题发送给客户端时,当前时间存储在会话中。这可以确保在发送谜题之后立即开始计时。完成拼图后,将其发送到服务器以检查是否完成了拼图,服务器再次检查时间并进行比较。
Obviously slow Internet connections can make this time bigger, but there's nothing you can do about it.
显然,缓慢的互联网连接可以让这段时间变得更大,但你对此无能为力。
#1
9
This approach obviously makes assumptions and is not invincible. All calculations are done on the client, and the server does some background checks to find out if the request could have been forged. Like any other client-based approach, this is not deterministic but makes it very hard for a lying client.
这种方法显然会做出假设,而且不是不可战胜的。所有计算都在客户机上完成,服务器进行一些背景检查,以确定请求是否伪造。与其他任何基于客户端的方法一样,这不是确定性的,但对于撒谎的客户来说,这非常困难。
The main assumption is that long-lived HTTP connections are much faster for transmitting data, even negligible in some cases depending on the application context. It is used in most online trading systems as stock prices can change multiple times within a second, and this is the fastest way to transmit current price to users. You can read up more about HTTP Streaming or Comet here.
主要假设是,长生命周期的HTTP连接传输数据的速度要快得多,甚至在某些情况下可以忽略,这取决于应用程序上下文。大多数在线交易系统都使用它,因为股价可以在一秒钟内多次变化,这是将当前价格传递给用户的最快方式。您可以在这里阅读更多关于HTTP流或Comet的信息。
Start by creating a full-duplex ajax connection between the client and server. The server has a dedicated line to talk to the client, and the client can obviously talk to the server. The server sends the puzzle, and other messages to the client on this dedicated line. The client is supposed to confirm the receipt of each message to the server along with its local timestamp.
首先创建客户端和服务器之间的全双工ajax连接。服务器有专线与客户端对话,客户端显然可以与服务器对话。服务器将难题和其他消息发送到此专用行的客户端。客户端应该确认每个消息的接收情况以及服务器的本地时间戳。
On the server generate random tokens (could be just distinct integers) after the puzzle has been sent, record the time when each token was generated, and pass it over to the client. The client sees the message, and is supposed to immediately relay this token back along with it's local time of receipt. To make it unpredictable for the client, generate these server tokens at random intervals, say between 1
and n
ms.
在服务器上生成随机令牌(可能只是不同的整数),然后记录生成每个令牌的时间,并将其传递给客户端。客户端看到消息,并且应该立即将此令牌转发给本地时间的收据。为了使客户端不可预测,在1和n ms之间随机生成这些服务器令牌。
There would be three types of messages that the client sends to the server:
客户端会向服务器发送三种类型的消息:
PUZZLE_RECEIVED
TOKEN_RECEIVED
PUZZLE_COMPLETED
And two types of messages that the server sends to the client:
以及服务器发送给客户的两种消息:
PUZZLE_SENT
TOKEN_SENT
There could be a lot of time variation in the messages send from the client to the server, but much lesser in the other direction (and that's a very fair assumption, hey - we have to start somewhere).
从客户端发送到服务器的消息可能有很多时间上的差异,但在另一个方向上的差异要小得多(这是一个非常合理的假设,嘿——我们必须从某个地方开始)。
Now when the server receives a receipt to a message it sent, record the client time contained in that message. Since the token was also relayed back in this message, we can match it with the corresponding token on the server. At the end of the puzzle, the client sends a PUZZLE_COMPLETED
message with local time to the server. The time to complete the puzzle would be:
现在,当服务器接收到它发送的消息的收据时,记录该消息中包含的客户端时间。由于该令牌也在此消息中被转发,所以我们可以将它与服务器上的相应令牌进行匹配。在难题结束时,客户端向服务器发送带有本地时间的PUZZLE_COMPLETED消息。完成这个难题的时间是:
PUZZLE_COMPLETED.time - PUZZLE_RECEIVED.time
Then double check by calculating the time difference in each message's sent vs received times.
然后通过计算每个消息的发送时间和接收时间的时间差来再次检查。
PUZZLE_RECEIVED.time - PUZZLE_SENT.time
TOKEN_RECEIVED.time - TOKEN_SENT.time
A high variance in these times implies that the response could have been forged. Besides simple variance, there is lots of statistical analysis you can do on this data to look for odd patterns.
在这些时间内的高方差意味着响应可能是伪造的。除了简单的方差,您还可以对这些数据进行大量的统计分析,以查找奇数模式。
#2
12
You can't guarantee the security of the timings cryptographically, because the client's browser can't do secure computation. Any means for encrypting to/from the server could be bypassed by adjusting the actual timings.
您不能以密码方式保证计时的安全性,因为客户机的浏览器不能进行安全计算。任何对服务器进行加密的方法都可以通过调整实际的时间来绕过。
And timing on the server doesn't work, either - if you don't take account of latency in the round-trip-time, users with lower latency connections will have an advantage; if you do, users could thwart the compensation phase by adding extra latency there and then removing it later.
服务器上的时间安排也不起作用——如果不考虑往返时间中的延迟,具有较低延迟连接的用户将具有优势;如果您这样做,用户可以在补偿阶段添加额外的延迟,然后在稍后删除它。
You can, of course make it difficult for the users to modify this, but security by obscurity is an unsustainable policy anyway.
当然,您可以让用户很难修改它,但是不透明的安全性是不可持续的策略。
So it comes down to either trusting your users somewhat (a reasonable assumption, most of the time) and designing the game so it's not trivial to circumvent the timings.
因此,它可以归结为信任您的用户(在大多数情况下是合理的假设)和设计游戏,以避免浪费时间。
#3
8
Even a compiled application could be forged. If the user changes their system clock halfway through timing, your application will report an incorrect time to the server. The only way to get an accurate upper-bound on the time it takes them is to start timing on the server when the puzzle is given to them, and to stop timing when they supply the answer.
即使编译好的应用程序也可以伪造。如果用户在计时过程中更改了系统时钟,您的应用程序将向服务器报告错误的时间。要在所需的时间上获得准确的上限,唯一的方法是在给他们难题时在服务器上开始计时,并在他们提供答案时停止计时。
As others have pointed out you can minimise the effect that slow connections have by making the load of the puzzle as small as possible. Load the entire page and "game engine" first, and then use an asynchronous request to load the puzzle itself (which should be a small amount of data) to level the playing field as much as possible.
正如其他人指出的那样,你可以通过使拼图的负载尽可能小来最小化慢速连接的影响。首先加载整个页面和“游戏引擎”,然后使用一个异步请求来加载拼图本身(应该是少量的数据),以尽可能地使游戏更加公平。
Unfortunately you can't do latency compensation as this would be open to tampering. However, on a connection that's not being used for anything else, the latency for a request like this would be greatly overshadowed by the time it takes a human to solve a puzzle, I don't think it will be a big deal.
不幸的是,您不能执行延迟补偿,因为这将会被篡改。然而,在一个没有被用于任何其他用途的连接上,像这样的请求的延迟将被人类解决难题所需的时间所掩盖,我认为这不是什么大问题。
(Reasoning: 200ms is considered very bad lag, and that's the average human reaction time. The shortest possible "puzzle" for a human to complete would be a visual reaction speed test, in which case bad lag would have a 100% markup on their results. So as a timing solution this is 2-OPT. Any puzzle more complex will be impacted less by lag.)
(推理:200ms被认为是非常糟糕的滞后,这是人类的平均反应时间。人类完成的最短的“谜题”可能是视觉反应速度测试,在这种情况下,糟糕的滞后将在他们的结果上有100%的标记。作为一个定时解决方案,这是2-OPT。任何更复杂的难题都会因滞后而减少。
I would also put a banner on the page saying to not use the internet connection for anything else while playing for the best possible speeds, possibly linking to a speed / latency tester.
我还会在页面上放一个横幅,上面写着在播放尽可能快的速度时不要使用互联网连接,可能会链接到速度/延迟测试器。
#4
4
It is impossible to start and stop the timer at the client-side without fear of manipulation...
在客户端启动和停止计时器是不可能的,而不必担心操作……
Anything you perform at the client can be altered / stopped / bypassed..
您在客户端执行的任何操作都可以更改/停止/绕过。
encrypting/decrypting at the client is also not safe since they can alter the info before the encryption occurs..
在客户端进行加密/解密也不安全,因为他们可以在加密发生之前修改信息。
Since it involves money, the users can not be trusted..
由于涉及到金钱,用户是不可信的。
The timing has to start at the server, and it has to stop at the server..
时间必须从服务器开始,它必须在服务器停止。
Use ajax to start the timer at the server only if the puzzle contents return with the result of the ajax call. do not load the puzzle and then sent an ajax request as this could be hijacked and delayed while they review the puzzle...
只有当难题内容返回到ajax调用的结果时,才使用ajax在服务器上启动计时器。不要加载迷惑,然后发送一个ajax请求,因为这可能会被劫持和延迟,因为在他们检查迷惑的时候……
..
. .
#5
3
Depending on the server side implementation you have, you could put the timing functionality on the server side. Record the time that the webpage request was made (you could put that into a database if you liked) and then when the answer is received get the current time and perform some arithmetic to get the duration of the answer. You could store the time in the session object if you liked instead of the database as well although I don't know too much about its integrity in there.
根据您所拥有的服务器端实现,您可以将计时功能放在服务器端。记录完成网页请求的时间(如果您愿意,可以将其放入数据库中),然后在接收到答案时获取当前时间并执行一些运算以获得答案的持续时间。您可以将时间存储在会话对象中,如果您喜欢,而不是数据库,尽管我不太了解它的完整性。
#6
3
You have to use server-side time here. Here is how I would do it:
这里必须使用服务器端时间。我是这样做的:
Make an AJAX request on document ready to ping the server. When server-side code receives the ping, store the server-side time as a session variable (making sure the variable does not already exist). When they finish the quiz, take the server-side time again and compare it with the session variable to determine their duration. Remove the session variable.
对准备ping服务器的文档发出AJAX请求。当服务器端代码接收到ping时,将服务器端时间存储为会话变量(确保该变量不存在)。当他们完成测试时,再次使用服务器端时间,并与会话变量进行比较,以确定测试的持续时间。删除会话变量。
Why this works:
为何如此:
- You do not start the timer before they see the quiz
- 你不能在他们看到测验之前就开始计时
- The network delay is factored in, because the timer does not start until the AJAX request comes in (if they have a slow connection, the AJAX request will be slow)
- 考虑到网络延迟,因为计时器直到AJAX请求进入才会启动(如果它们的连接很慢,那么AJAX请求就会很慢)
- Ping is not spoofable because you make sure the session variable does not exist before storing
- Ping是不可欺骗的,因为您要确保在存储之前会话变量不存在
EDIT: I wanted to add that you could continue to keep client-side time, and include it in the final post. Then you can compare it with your server-side calculated time. If they are reasonably close, then you can trust the client time.
编辑:我想补充一点,您可以继续保持客户端时间,并将其包含在最终的帖子中。然后您可以将其与服务器端计算的时间进行比较。如果它们非常接近,那么您可以信任客户的时间。
#7
2
You asked a bunch of questions in your original question, I'm only going to answer one of them:
你问了很多问题,我只回答其中一个
Am I going to have to use something that gets compiled, like Flash? (Yikes.)
我需要使用一些编译过的东西吗,比如Flash?(呀!)
Yes. Given your criteria: 1) 100% accurate, and 2) No possibility of user interference, you have to use a compiled binary.
是的。给定您的标准:1)100%准确,2)不存在用户干扰,您必须使用编译后的二进制文件。
Doesn't have to be flash though - I'd suggest a java applet if the thought of Flash makes you say "Yikes".
不过不一定非得是flash——如果一想到flash你就会说“Yikes”,我建议你使用java applet。
#8
2
-- Edit:
——编辑:
This solution is somewhat flawed, as pointed out by ZoFrex below.
正如下面ZoFrex指出的,这个解决方案有些缺陷。
-- Old:
——老:
Here is a way (but you'll need to do some profiling).
这里有一个方法(但您需要做一些分析)。
Send down a series of "problems" for the JavaScript to solve, while they are playing the puzzle. Previously, I've sufficiently-sized number N such that it is the result of: prime1 * prime2. This forces the client to factor the number (you can get code to do this in JavaScript) and this will take time (this is where profiling clients comes in, and sending down appropriately-sized primes [obviously, this opens you to degradation-attacks, but nevertheless]).
在他们玩拼图游戏的时候,给JavaScript发送一系列“问题”来解决。之前,我有一个足够大的数字N,这样的结果是:prime1 * prime2。这将迫使客户端对数字进行分解(您可以用JavaScript编写代码来实现这一点),这将需要时间(这就是分析客户端进入的地方,并发送适当大小的质数(显然,这将导致降级攻击,但无论如何)。
Then, you just send down say, 500, of these prime-problems (or another type), and let the JavaScript solve them in the background. It will generate a list of solutions, and when you send the completed value, you also send this list. From the total count of answers supplied, you can determine how long they spent on the puzzle.
然后,你只需发送500个这样的主要问题(或其他类型),让JavaScript在后台解决它们。它将生成一个解决方案列表,当您发送完成的值时,您也将发送这个列表。从所提供的答案总数中,您可以确定他们在这个难题上花费了多长时间。
Cons:
缺点:
- Requires profiling to determine capabilities of various clients (and hence difficulty of problems)
- 要求概要分析以确定各种客户机的功能(因此存在问题)
- Can be downgrade-attacked
- 可以downgrade-attacked
- Slightly complicated
- 稍微复杂的
- JavaScript computation may interrupt general puzzle-solving
- JavaScript计算可能会中断一般的解谜
- Possible to write a bot to get solve problems faster than JS
- 可以编写一个比JS更快的机器人来解决问题
Pros:
优点:
- Calculations must be done in order to submit the form
- 为了提交表格,必须进行计算
- If implemented correctly, will prevent all but non-trivial attacks
- 如果实现正确,将避免所有的攻击
Clearly, it's attackable, (all proposed answers are), but I think it's reasonable. At least, it would be fun to work on :)
显然,这是可以攻击的(所有提议的答案都是),但我认为这是合理的。至少,它将是有趣的工作:)
In the end, though, you need to actually install a client-side system with a bit more security. And do note that Flash certainly is not this; it's trivial to decompile. Infact, there was an IQ test here in Australia once, and it was controlled via a Flash app that was done LIVE on television. Of course, the winner was a computer programmer, I wonder why :P
不过,最终您需要实际安装一个具有更多安全性的客户端系统。请注意,Flash肯定不是这个;反编译是微不足道的。事实上,澳大利亚曾经有过一次IQ测试,它是通过在电视上直播的Flash应用来控制的。当然,获胜者是一个计算机程序员,我想知道为什么:P
-- Edit:
——编辑:
OP, Also, I linked it in a comment to this post, but just incase you miss it, you are kind of interested in the Hashcash, which is the aim to show that a client has completed some amount of 'Work'. Even if my implementation isn't suitable, you may find a review of that field fruitful.
OP,同样,我在一个评论中把它链接到这篇文章,但是如果你错过了,你会对Hashcash感兴趣,它的目的是显示客户已经完成了一些“工作”。即使我的实现不合适,您可能会发现对该领域的审查结果很有成效。
#9
2
It's a tricky problem because it's fundamentally unsolvable, so you need to work around the tradeoffs to do your best. There've been several good points made on the technical side including: (a) don't waste your time thinking compiling to Flash, Windows, Silverlight, JVM, or anything will actually help, (b) first transmit the encrypted real puzzle payload, then as the actual bottleneck transmit the key alone, (c) the latency even on 56k of sending a couple hundred bytes is negligible compared to human reaction time.
这是一个棘手的问题,因为它从根本上来说是无法解决的,所以你需要围绕权衡来尽你最大的努力。有几个好点的技术方面,包括:(a)别浪费时间思考编译Flash,窗户,Silverlight,JVM,或者任何会帮助,(b)首先传输加密的真正难题有效载荷,当实际传输的关键瓶颈,(c)即使在56 k的延迟发送几百字节是人类反应时间相比可以忽略不计。
One thing I haven't seen mentioned is this:
有一件事我没有提到:
Use after-the-fact auditing and tracking of users. This is how real casinos work. This is, I am told, a big part of how PayPal made their money. In both cases, rather than doing a lot of before-the-fact security, they keep very close tabs on everything about their players, use a lot of technology (statistics, pattern detection, etc) to flag suspicious players and they investigate. In both casinos and PayPal, you can't get your money right away. You have to cash in your chips or wait for the money to make it out of the PayPal system into your real bank. Your system should work the same way-- they can't actually get the money for at least a few days at minimum (longer if you are unable to set up a sufficiently speedy auditing system), giving you time to potentially impound their winnings. You have a lawyer, right? Also, casinos and PayPal know your real life identity (a must for dealing in money) so they can go after you legally-- or more importantly, deter would-be attackers since they could go after them legally.
使用事后审计和用户跟踪。这就是真正的赌场的运作方式。我听说,这是贝宝赚钱的一个重要原因。在这两种情况下,他们不会做很多事前安全工作,而是密切关注玩家的一切,使用大量的技术(统计数据、模式检测等)来标记可疑的玩家,并进行调查。在赌场和贝宝,你不能马上拿到钱。你必须把你的芯片换成现金,或者等到钱从贝宝系统转到你真正的银行。您的系统应该以同样的方式工作——他们实际上至少不能获得几天的资金(如果您无法建立一个足够快速的审计系统,则需要更长的时间),从而让您有时间没收他们的奖金。你有律师,对吧?此外,赌场和贝宝知道你的真实身份(在金钱交易中必须具备的身份),这样他们就可以合法地追捕你——或者更重要的是,阻止潜在的攻击者,因为他们可以合法地追捕他们。
Combined with the other tips, this may be sufficient to eliminate cheating entirely.
结合其他技巧,这可能足以完全消除作弊。
If you find it is not, make your goal not to totally eliminate cheating but to keep it to an acceptable level. Kind of like having 99.99% uptime. Yes, as one poster said, if even one person can compromise it everyone is screwed, but with a good auditing system the attacker won't be able to consistently cheat. If they can cheat 1 in 1000 times if they're lucky and they find they can't cheat more than once or twice before being caught, it won't be a problem since very few will cheat and any given honest user will have an extremely low chance of being affected by an extremely small amount of cheating. It'll be imperceptible. If you ever have a real cheating occurence that hurts an honest user, go out of your way to make the honest user feel satisfied with the outcome to a degree out of proportion to the value of that single customer. That way everyone will be confident in your security. They know they don't have to worry about anything.
如果你发现它不是,让你的目标不是完全消除作弊,而是保持一个可接受的水平。有点像99.99%的正常运行时间。是的,就像一张海报说的那样,如果一个人可以妥协,那么每个人都完蛋了,但是有了一个好的审计系统,攻击者就不会一直作弊了。如果他们能欺骗1 1000年*如果他们幸运,他们发现他们不能欺骗一次或两次以上被抓之前,它不会是一个问题,因为很少会欺骗和任何诚实的用户将受到影响的几率极低极少量的作弊。它会听不清。如果你真的有过欺骗行为,伤害了一个诚实的用户,那就尽力让诚实的用户在一定程度上对结果感到满意。这样每个人都会对你的安全充满信心。他们知道他们什么都不用担心。
People problems are not always solvable with technology solutions alone. You sometimes need to use people solutions. (The technology can help those people solutions work a lot better though.)
人的问题并不总是单靠技术解决的。你有时需要使用人员解决方案。(不过,这项技术可以帮助这些人更好地解决问题。)
#10
1
excuse me but why you can't use the time on the server? the time when you recieve the response will be the one which you use to calculate the score.
对不起,你为什么不能在服务器上使用时间?您收到响应的时间将是您用来计算分数的时间。
#11
1
As several others have pointed out:
正如其他几个人指出的那样:
- You must use server time, because client time is vulnerable to manipulation.
- 您必须使用服务器时间,因为客户机时间容易被操纵。
- Checking the time on the server will potentially penalize people with slow network connections, or people that are far away.
- 检查服务器上的时间可能会惩罚网络连接缓慢的人,或者远程的人。
The answer to the problem is to use a time synchronization protocol between the client and the server similar to the protocol that NTP uses. Working together, the client and the server determine the amount of delay caused by network latency. This is then factored into the times given to each user.
问题的答案是在客户端和服务器之间使用与NTP使用的协议类似的时间同步协议。在一起工作时,客户机和服务器决定网络延迟所导致的延迟量。然后将其分解为给每个用户的时间。
NTP's algorithms are complicated and have been developed over years. But a simple approach is below; I think that the protocol should work, but you may wish to test it.
NTP算法是复杂的,并且已经发展多年。下面是一个简单的方法;我认为协议应该有效,但是您可能希望测试它。
Have the client measure the round-trip time with two successive HTTP XMLRPC pings. Each ping returns a different nonce. The second ping requires the nonce from the first ping, which assures that they are sequential. The puzzle time starts when the second HTTP ping is sent from the client. The server timestamps each request and assumes that the puzzle is displayed 1/2 way between the receipt of the first and the second request.
让客户端使用两个连续的HTTP XMLRPC ping来度量往返时间。每个ping返回一个不同的nonce。第二个ping需要来自第一个ping的nonce,这确保它们是连续的。当从客户端发送第二个HTTP ping时,问题开始了。服务器为每个请求设置时间戳,并假定迷惑显示在收到第一个请求和第二个请求之间的半路上。
When the puzzle is finished the client pings twice again, following the same protocol as before. The server knows when it receives each request and it knows the time delta. Now take half the time delta and subtract that from when the first ping of the second set is received. That can be safely assumed to be the time that the puzzle was completed.
当这个难题再次完成时,客户端会重复两次,遵循和以前一样的协议。服务器知道何时接收每个请求,并知道时间增量。现在取一半的时间增量,减去接收到第二组第一个ping信号时的时间增量。可以有把握地假定这是完成这个谜题的时间。
#12
0
there is a very fast implementation of cryptography in js here
在js中有一个非常快速的加密实现
http://crypto.stanford.edu/sjcl/
http://crypto.stanford.edu/sjcl/
it allows public / private key encryption all on the client and I think you can adapt it to encrypt the Ajax communication between your server and the client browser
它允许在客户机上进行公钥/私钥加密,我认为您可以对它进行调整,以便对服务器和客户机浏览器之间的Ajax通信进行加密
here is a detailed explanation, which you can adapt to your needs http://crypto.stanford.edu/sjcl/#usage
这里有一个详细的解释,您可以根据自己的需要(http://crypto.stanford.edu/sjcl/#usage)
#13
0
Just a quick thought: why don't you use an iFrame to include the game and it's javascripts and let them reside on the server you have your server side implementation running. Any ajax request should then be sent by the same IP as your server side IP is which would solve the problem of identifying the source. Of course you have to take further measures but already gained a lot of confidence in your "client" side requests. Remember the windowsLive services login and many more like it are based on javascript and the usage of iFrames and are considered secure enough.
简单地想一下:为什么不使用iFrame来包含这个游戏,它是javascript,让它们驻留在服务器上,让服务器端实现运行。然后,任何ajax请求都应该由与服务器端IP相同的IP发送,这将解决标识源的问题。当然,你必须采取进一步的措施,但你已经对“客户”方面的要求有了很大的信心。请记住,windowsLive服务登录以及其他类似的功能都是基于javascript和iframe的使用,并被认为足够安全。
#14
0
I do not think there is a perfect solution. Here is an alternative that makes it harder for cheater but at the same time an unlucky honest solver may lose out.
我认为没有完美的解决方案。这是另一种选择,它使骗子更难,但同时一个不幸的诚实的解决者可能会失去。
Get many samples of roundtrip time measurements from each specific devices/location/other combination apriori for each user based on their other interaction with your site. You will also have these measurements for the entire population. You could also be very subtle get the timestamps for when a particular DNS lookup happened from their ISP's resolver (random hostname and you host the authoritative DNS server for that domain).
根据每个用户与站点的其他交互,从每个特定的设备/位置/其他组合中获取许多往返时间度量的示例。你还可以对整个群体进行测量。您还可以非常巧妙地从其ISP解析器(随机主机名,并托管该域的权威DNS服务器)获取特定DNS查找发生的时间戳。
Once you have this, perform all measurements on the server side (puzzle returned to user, solution received) and subtract out the network time based on previous observations.
一旦您有了这个,在服务器端执行所有的度量(难题返回给用户,解决方案接收),并根据以前的观察减去网络时间。
Note that even in other solutions you have server load, client load (slow processor, etc.), etc that affect timing.
注意,即使在其他解决方案中,服务器负载、客户端负载(慢处理器等)等也会影响时间。
Make sure you have XSRF protection on puzzle submission page :)
确保您在拼图提交页面上有XSRF保护:)
#15
-4
The way I would do this is that when the server sends the puzzle to the client, the current time is stored in a session. This ensures that the timing starts immediately after the puzzle has been sent. After the puzzle has been completed, and is sent to the server to check if the puzzle was done right, the server again checks the time and does a comparison.
我这样做的方法是,当服务器将难题发送给客户端时,当前时间存储在会话中。这可以确保在发送谜题之后立即开始计时。完成拼图后,将其发送到服务器以检查是否完成了拼图,服务器再次检查时间并进行比较。
Obviously slow Internet connections can make this time bigger, but there's nothing you can do about it.
显然,缓慢的互联网连接可以让这段时间变得更大,但你对此无能为力。